[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-7064":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":21,"defaultBranch":22,"hasWiki":21,"hasPages":21,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":33,"readmeContent":34,"aiSummary":35,"trendingCount":16,"starSnapshotCount":16,"syncStatus":17,"lastSyncTime":36,"discoverSource":37},7064,"Tokamak","TokamakUI\u002FTokamak","TokamakUI","[Looking for active maintainers] SwiftUI-compatible framework for building browser apps with WebAssembly and native apps for other platforms","",null,"Swift",2843,127,51,113,0,2,58.52,"Apache License 2.0",true,false,"main",[24,25,26,27,28,29,30,31,32],"data-binding","dom","hacktoberfest","swift","swiftui","swiftwasm","ui-components","wasi","webassembly","2026-06-12 04:00:32","\u003Cimg alt=\"Tokamak logo\" src=\"Sources\u002FTokamakDemo\u002Flogo-header.png\" width=\"640px\"\u002F>\n\n## SwiftUI-compatible framework for building browser apps with WebAssembly\n\n[![CI status](https:\u002F\u002Fgithub.com\u002Fswiftwasm\u002FTokamak\u002Fworkflows\u002FCI\u002Fbadge.svg?branch=main)](https:\u002F\u002Fgithub.com\u002FTokamakUI\u002FTokamak\u002Factions?query=workflow%3ACI) [![Discord](https:\u002F\u002Fimg.shields.io\u002Fdiscord\u002F780838335798706197?label=Discord)](https:\u002F\u002Fdiscord.gg\u002FashJW8T8yp)\n\nAt the moment Tokamak implements a very basic subset of SwiftUI. Its DOM renderer supports a few\nview types and modifiers (you can check the current list in [the progress\ndocument](docs\u002Fprogress.md)), and a new `HTML` view for constructing arbitrary HTML. The long-term\ngoal of Tokamak is to implement as much of SwiftUI API as possible and to provide a few more helpful\nadditions that simplify HTML and CSS interactions.\n\nIf there's some SwiftUI API that's missing but you'd like to use it, please review the existing\n[issues](https:\u002F\u002Fgithub.com\u002Fswiftwasm\u002FTokamak\u002Fissues) and\n[PRs](https:\u002F\u002Fgithub.com\u002Fswiftwasm\u002FTokamak\u002Fpulls) to get more details about the current status, or\n[create a new issue](https:\u002F\u002Fgithub.com\u002Fswiftwasm\u002FTokamak\u002Fissues\u002Fnew) to let us prioritize the\ndevelopment based on the demand. We also try to make the development of views and modifiers easier\n(with the help from the `HTML` view, see [the example\nbelow](https:\u002F\u002Fgithub.com\u002Fswiftwasm\u002FTokamak#arbitrary-html)), so pull requests are very welcome!\nDon't forget to check [the \"Contributing\"\nsection](https:\u002F\u002Fgithub.com\u002Fswiftwasm\u002FTokamak#contributing) first.\n\nIf you'd like to participate in the growing [SwiftWasm](https:\u002F\u002Fswiftwasm.org) community, you're\nalso very welcome to join [our Discord server](https:\u002F\u002Fdiscord.gg\u002FashJW8T8yp), or the `#webassembly`\nchannel in [the SwiftPM Slack](https:\u002F\u002Fswift-package-manager.herokuapp.com\u002F).\n\n### Example code\n\nTokamak API attempts to resemble SwiftUI API as much as possible. The main difference is\nthat you use `import TokamakShim` instead of `import SwiftUI` in your files. The former makes\nyour views compatible with Apple platforms, as well as platforms supported by Tokamak (currently\nonly WebAssembly\u002F[WASI](https:\u002F\u002Fwasi.dev\u002F) with more coming in the future):\n\n```swift\nimport TokamakShim\n\nstruct Counter: View {\n  @State var count: Int\n  let limit: Int\n\n  var body: some View {\n    if count \u003C limit {\n      VStack {\n        Button(\"Increment\") { count += 1 }\n        Text(\"\\(count)\")\n      }\n      .onAppear { print(\"Counter.VStack onAppear\") }\n      .onDisappear { print(\"Counter.VStack onDisappear\") }\n    } else {\n      VStack { Text(\"Limit exceeded\") }\n    }\n  }\n}\n\n@main\nstruct CounterApp: App {\n  var body: some Scene {\n    WindowGroup(\"Counter Demo\") {\n      Counter(count: 5, limit: 15)\n    }\n  }\n}\n```\n\n### Arbitrary HTML\n\nWith the `HTML` view you can also render any HTML you want, including inline SVG:\n\n```swift\nstruct SVGCircle: View {\n  var body: some View {\n    HTML(\"svg\", [\"width\": \"100\", \"height\": \"100\"]) {\n      HTML(\"circle\", [\n        \"cx\": \"50\", \"cy\": \"50\", \"r\": \"40\",\n        \"stroke\": \"green\", \"stroke-width\": \"4\", \"fill\": \"yellow\",\n      ])\n    }\n  }\n}\n```\n\n`HTML` doesn't support event listeners, and is declared in the `TokamakStaticHTML` module, which `TokamakDOM` re-exports. The benefit of `HTML` is that you can use it for static rendering in libraries like [TokamakVapor](https:\u002F\u002Fgithub.com\u002FTokamakUI\u002FTokamakVapor) and [TokamakPublish](https:\u002F\u002Fgithub.com\u002FTokamakUI\u002FTokamakPublish).\n\nAnother option is the `DynamicHTML` view provided by the `TokamakDOM` module, which has a `listeners` property with a corresponding initializer parameter. You can pass closures that can handle `onclick`, `onmouseover` and other DOM events for you in the `listeners` dictionary. Check out [MDN docs](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FGlobalEventHandlers) for the full list.\n\nAn example of mouse events handling with `DynamicHTML` would look like this:\n\n```swift\nstruct MouseEventsView: View {\n  @State var position: CGPoint = .zero\n  @State var isMouseButtonDown: Bool = false\n\n  var body: some View {\n    DynamicHTML(\n      \"div\",\n      [\"style\": \"width: 200px; height: 200px; background-color: red;\"],\n      listeners: [\n        \"mousemove\": { event in\n          guard\n            let x = event.offsetX.jsValue.number,\n            let y = event.offsetY.jsValue.number\n          else { return }\n\n          position = CGPoint(x: x, y: y)\n        },\n        \"mousedown\": { _ in isMouseButtonDown = true },\n        \"mouseup\": { _ in isMouseButtonDown = false },\n      ]\n    ) {\n      Text(\"position is \\(position), is mouse button down? \\(isMouseButtonDown)\")\n    }\n  }\n}\n```\n\n### Arbitrary styles and scripts\n\nWhile [`JavaScriptKit`](https:\u002F\u002Fgithub.com\u002Fswiftwasm\u002FJavaScriptKit) is a great option for occasional interactions with JavaScript,\nsometimes you need to inject arbitrary scripts or styles, which can be done through direct\nDOM access:\n\n```swift\nimport JavaScriptKit\n\nlet document = JSObject.global.document\nlet script = document.createElement(\"script\")\nscript.setAttribute(\"src\", \"https:\u002F\u002Fcdnjs.cloudflare.com\u002Fajax\u002Flibs\u002Fmoment.js\u002F2.27.0\u002Fmoment.min.js\")\ndocument.head.appendChild(script)\n\n_ = document.head.insertAdjacentHTML(\"beforeend\", #\"\"\"\n\u003Clink\n  rel=\"stylesheet\"\n  href=\"https:\u002F\u002Fcdnjs.cloudflare.com\u002Fajax\u002Flibs\u002Fsemantic-ui\u002F2.4.1\u002Fsemantic.min.css\">\n\"\"\"#)\n```\n\nThis way both [Semantic UI](https:\u002F\u002Fsemantic-ui.com\u002F) styles and [moment.js](https:\u002F\u002Fmomentjs.com\u002F)\nlocalized date formatting (or any arbitrary style\u002Fscript\u002Ffont added that way) are available in your\napp.\n\n### Fiber renderers\n\nA new reconciler modeled after React's [Fiber reconciler](https:\u002F\u002Freactjs.org\u002Fdocs\u002Ffaq-internals.html#what-is-react-fiber)\nis optionally available. It can provide faster updates and allow for larger View hierarchies.\nIt also includes layout steps that can match SwiftUI layouts closer than CSS approximations.\n\nYou can specify which reconciler to use in your `App`'s configuration:\n\n```swift\nstruct CounterApp: App {\n  static let _configuration: _AppConfiguration = .init(\n    \u002F\u002F Specify `useDynamicLayout` to enable the layout steps in place of CSS approximations.\n    reconciler: .fiber(useDynamicLayout: true)\n  )\n\n  var body: some Scene {\n    WindowGroup(\"Counter Demo\") {\n      Counter(count: 5, limit: 15)\n    }\n  }\n}\n```\n\n> *Note*: Not all `View`s and `ViewModifier`s are supported by Fiber renderers yet.\n\n## Requirements\n\n### For app developers\n\n- macOS 11 and Xcode 13.2 or later when using VS Code. macOS 12 and Xcode 13.3 or later are recommended if\n  you'd like to use Xcode for auto-completion, or when developing multi-platform apps that target WebAssembly\n  and macOS at the same time.\n- [Swift 5.6 or later](https:\u002F\u002Fswift.org\u002Fdownload\u002F) and Ubuntu 18.04\u002F20.04 if you'd like to use Linux.\n  Other Linux distributions are currently not supported.\n- [`carton` 0.15.x](https:\u002F\u002Fcarton.dev) (carton is our build tool, see the [\"Getting started\" section](#getting-started) for installation steps)\n\n### For users of apps depending on Tokamak\n\nAny recent browser that [supports WebAssembly](https:\u002F\u002Fcaniuse.com\u002F#feat=wasm) and [required\nJavaScript features](https:\u002F\u002Fcaniuse.com\u002F?search=finalizationregistry) should work, which currently includes:\n\n- Edge 84+\n- Firefox 79+\n- Chrome 84+\n- Desktop Safari 14.1+\n- Mobile Safari 14.8+\n\nIf you need to support older browser versions, you'll have to build with\n`JAVASCRIPTKIT_WITHOUT_WEAKREFS` flag, passing `-Xswiftc -DJAVASCRIPTKIT_WITHOUT_WEAKREFS` flags\nwhen compiling. This should lower browser requirements to these versions:\n\n- Edge 16+\n- Firefox 61+\n- Chrome 66+\n- (Mobile) Safari 12+\n\nNot all of these versions are tested on regular basis though, compatibility reports are very welcome!\n\n## Getting started\n\nTokamak relies on [`carton`](https:\u002F\u002Fcarton.dev) as a primary build tool. As a part of these steps\nyou'll install `carton` via [Homebrew](https:\u002F\u002Fbrew.sh\u002F) on macOS (unfortunately you'll have to build\nit manually on Linux). Assuming you already have Homebrew installed, you can create a new Tokamak\napp by following these steps:\n\n1. Install `carton`:\n\n```\nbrew install swiftwasm\u002Ftap\u002Fcarton\n```\n\nIf you had `carton` installed before this, make sure you have version 0.15.0 or greater:\n\n```\ncarton --version\n```\n\n2. Create a directory for your project and make it current:\n\n```\nmkdir TokamakApp && cd TokamakApp\n```\n\n3. Initialize the project from a template with `carton`:\n\n```\ncarton init --template tokamak\n```\n\n4. Build the project and start the development server, `carton dev` can be kept running\n   during development:\n\n```\ncarton dev\n```\n\n5. Open [http:\u002F\u002F127.0.0.1:8080\u002F](http:\u002F\u002F127.0.0.1:8080\u002F) in your browser to see the app\n   running. You can edit the app source code in your favorite editor and save it, `carton`\n   will immediately rebuild the app and reload all browser tabs that have the app open.\n\nYou can also clone this repository and run `carton dev --product TokamakDemo` in its root\ndirectory. This will build the demo app that shows almost all of the currently implemented APIs.\n\nIf you have any questions, pleaes check out the [FAQ](docs\u002FFAQ.md) document, and\u002For join the\n#tokamak channel on [the SwiftWasm Discord server](https:\u002F\u002Fdiscord.gg\u002FashJW8T8yp).\n\n## Security\n\nBy default, the DOM renderer will escape HTML control characters in `Text` views. If you wish\nto override this functionality, you can use the `_domTextSanitizer` modifier:\n\n```swift\nText(\"\u003Cfont color='red'>Unsanitized Text\u003C\u002Ffont>\")\n  ._domTextSanitizer(Sanitizers.HTML.insecure)\n```\n\nYou can also use custom sanitizers; the argument to `_domTextSanitizer` is simply a\n`String -> String` closure. If `_domTextSanitizer` is applied to a non-`Text` view,\nit will apply to all `Text` in subviews, unless overridden.\n\nIf you use user-generated or otherwise unsafe strings elsewhere, make sure to properly\nsanitize them yourself.\n\n## Troubleshooting\n\n### `unable to find utility \"xctest\"` error when building\n\nThis error can only happen on macOS, so make sure you have Xcode installed as listed [in the\nrequirements](#requirements-for-app-developers). If you do have Xcode installed but still get the\nerror, please refer to [this StackOverflow answer](https:\u002F\u002Fstackoverflow.com\u002Fa\u002F61725799\u002F442427).\n\n### Syntax highlighting and autocomplete don't work in Xcode\n\nOpen `Package.swift` of your project that depends on Tokamak with Xcode and build it for macOS.\nAs Xcode currently doesn't support cross-compilation for non-Apple platforms, your project can't\nbe indexed if it doesn't build for macOS, even if it isn't fully function on macOS when running.\nIf you need to exclude some WebAssembly-specific code in your own app that doesn't compile on macOS,\nyou can rely on `#if os(WASI)` compiler directives.\n\nAll relevant modules of Tokamak (including `TokamakDOM`) should compile on macOS. You may see issues\nwith `TokamakShim` on macOS Catalina, where relevant SwiftUI APIs aren't supported, but replacing\n`import TokamakShim` with `import TokamakDOM` should resolve the issue until you're able to update\nto macOS Big Sur.\n\nIf you stumble upon code in Tokamak that doesn't build on macOS and prevents syntax highlighting or\nautocomplete from working in Xcode, please [report it as a\nbug](https:\u002F\u002Fgithub.com\u002FTokamakUI\u002FTokamak\u002Fissues\u002Fnew).\n\n### Syntax highlighting and autocomplete don't work in VSCode\n\nMake sure you have [the SourceKit LSP\nextension](https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=pvasek.sourcekit-lsp--dev-unofficial)\ninstalled. If you don't trust this unofficial release, please follow [the manual building and\ninstallation guide](https:\u002F\u002Fgithub.com\u002Fapple\u002Fsourcekit-lsp\u002Ftree\u002Fmain\u002FEditors\u002Fvscode). Apple currently\ndoesn't provide an official build of the extension on the VSCode Marketplace unfortunately.\n\n## Contributing\n\nAll contributions, no matter how small, are very welcome. You don't have to be a web developer or a\nSwiftUI expert to meaningfully contribute. In fact, by checking out how some of the simplest views are\nimplemented in Tokamak you may learn more how SwiftUI may work under the hood.\n\nUpdating our [documentation](https:\u002F\u002Fgithub.com\u002FTokamakUI\u002FTokamak\u002Ftree\u002Fmain\u002Fdocs) and taking on [the starter\nbugs](https:\u002F\u002Fgithub.com\u002FTokamakUI\u002FTokamak\u002Fissues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\nis also appreciated. Don't forget to join our [Discord server](https:\u002F\u002Fdiscord.gg\u002FashJW8T8yp) to get in\ntouch with the maintainers and other users. See [`CONTRIBUTING.md`](CONTRIBUTING.md) for more details.\n\n### Code of Conduct\n\nThis project adheres to the [Contributor Covenant Code of\nConduct](https:\u002F\u002Fgithub.com\u002Fswiftwasm\u002FTokamak\u002Fblob\u002Fmain\u002FCODE_OF_CONDUCT.md).\nBy participating, you are expected to uphold this code. Please report\nunacceptable behavior to conduct@tokamak.dev.\n\n### Sponsorship\n\nIf this library saved you any amount of time or money, please consider sponsoring\nthe work of its maintainers on their sponsorship pages:\n[@carson-katri](https:\u002F\u002Fgithub.com\u002Fsponsors\u002Fcarson-katri),\n[@kateinoigakukun](https:\u002F\u002Fgithub.com\u002Fsponsors\u002Fkateinoigakukun), and\n[@MaxDesiatov](https:\u002F\u002Fgithub.com\u002Fsponsors\u002FMaxDesiatov). While some of the\nsponsorship tiers give you priority support or even consulting time, any amount is\nappreciated and helps in maintaining the project.\n\n## Maintainers\n\nIn alphabetical order: [Carson Katri](https:\u002F\u002Fgithub.com\u002Fcarson-katri),\n[Ezra Berch](https:\u002F\u002Fgithub.com\u002Fezraberch),\n[Jed Fox](https:\u002F\u002Fjedfox.com),\n[Morten Bek Ditlevsen](https:\u002F\u002Fgithub.com\u002Fmortenbekditlevsen\u002F),\n[Yuta Saito](https:\u002F\u002Fgithub.com\u002Fkateinoigakukun\u002F).\n\n## Acknowledgments\n\n- Thanks to the [Swift community](https:\u002F\u002Fswift.org\u002Fcommunity\u002F) for\n  building one of the best programming languages available!\n- Thanks to everyone who developed [React](https:\u002F\u002Freactjs.org\u002F) with its [reconciler\u002Frenderer\n  architecture](https:\u002F\u002Freactjs.org\u002Fdocs\u002Fcodebase-overview.html#renderers) that inspired Tokamak\n  in the first place.\n- Thanks to the designers of [the SwiftUI API](https:\u002F\u002Fdeveloper.apple.com\u002Fdocumentation\u002Fswiftui)\n  who showed us how to write UI apps in Swift declaratively (arguably even in a better way than React did).\n- Thanks to [SwiftWebUI](https:\u002F\u002Fgithub.com\u002FSwiftWebUI\u002FSwiftWebUI) for reverse-engineering\n  some of the bits of SwiftUI and kickstarting the front-end Swift ecosystem for the web.\n- Thanks to [Render](https:\u002F\u002Fgithub.com\u002Falexdrone\u002FRender),\n  [ReSwift](https:\u002F\u002Fgithub.com\u002FReSwift\u002FReSwift), [Katana\n  UI](https:\u002F\u002Fgithub.com\u002FBendingSpoons\u002Fkatana-ui-swift) and\n  [Komponents](https:\u002F\u002Fgithub.com\u002FfreshOS\u002FKomponents) for inspiration!\n\nSwiftUI is a trademark owned by Apple Inc. Software maintained as a part of the Tokamak project\nis not affiliated with Apple Inc.\n\n## License\n\nTokamak is available under the Apache 2.0 license.\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the [LICENSE](https:\u002F\u002Fgithub.com\u002Fswiftwasm\u002FTokamak\u002Fblob\u002Fmain\u002FLICENSE) file for\nmore info.\n","Tokamak 是一个兼容 SwiftUI 的框架，用于使用 WebAssembly 构建浏览器应用以及为其他平台构建原生应用。它通过实现 SwiftUI API 的子集，并提供了一个 DOM 渲染器来支持多种视图类型和修饰符，同时新增了 `HTML` 视图以构造任意 HTML 内容。Tokamak 旨在尽可能多地实现 SwiftUI 的功能，并简化与 HTML 和 CSS 的交互。该项目适合需要跨平台开发且希望利用 Swift 语言特性的开发者，特别是在 Web 环境下寻求一致开发体验的场景中非常有用。目前项目正在积极寻找维护者，欢迎贡献代码或参与社区讨论。","2026-06-11 03:10:21","top_language"]