Development fork of https://github.com/TokamakUI/Tokamak

Related tags

Animation Tokamak
Overview

Tokamak logo

SwiftUI-compatible framework for building browser apps with WebAssembly

CI status

At the moment Tokamak implements a very basic subset of SwiftUI. Its DOM renderer supports a few view types and modifiers (you can check the current list in the progress document), and a new HTML view for constructing arbitrary HTML. The long-term goal of Tokamak is to implement as much of SwiftUI API as possible and to provide a few more helpful additions that simplify HTML and CSS interactions.

If there's some SwiftUI API that's missing but you'd like to use it, please review the existing issues and PRs to get more details about the current status, or create a new issue to let us prioritize the development based on the demand. We also try to make the development of views and modifiers easier (with the help from the HTML view, see the example below), so pull requests are very welcome! Don't forget to check the "Contributing" section first.

If you'd like to participate in the growing SwiftWasm community, you're also very welcome to join the #webassembly channel in the SwiftPM Slack.

Getting started

Tokamak relies on carton as a primary build tool. Please follow installation instructions for carton first.

After carton is successfully installed, type carton dev --product TokamakDemo in the root directory of the cloned Tokamak repository. This will build the demo project and its dependencies and launch a development HTTP server. You can then open http://127.0.0.1:8080/ in your browser to interact with the demo.

Example code

Tokamak API attempts to resemble SwiftUI API as much as possible. The main difference is that you use import TokamakShim instead of import SwiftUI in your files. The former makes your views compatible with Apple platforms, as well as platforms supported by Tokamak (currently only WebAssembly/WASI with more coming in the future):

import TokamakShim

struct Counter: View {
  @State var count: Int
  let limit: Int

  var body: some View {
    if count < limit {
      VStack {
        Button("Increment") { count += 1 }
        Text("\(count)")
      }
      .onAppear { print("Counter.VStack onAppear") }
      .onDisappear { print("Counter.VStack onDisappear") }
    } else {
      VStack { Text("Limit exceeded") }
    }
  }
}

You can then render your view in any DOM node captured with JavaScriptKit, just pass it as an argument to the DOMRenderer initializer together with your view:

import JavaScriptKit
import TokamakDOM

let document = JSObjectRef.global.document.object!

let divElement = document.createElement!("div").object!
let renderer = DOMRenderer(Counter(count: 5, limit: 15), divElement)

let body = document.body.object!
_ = body.appendChild!(divElement)

Arbitrary HTML

With the HTML view you can also render any HTML you want, including inline SVG:

struct SVGCircle: View {
  var body: some View {
    HTML("svg", ["width": "100", "height": "100"]) {
      HTML("circle", [
        "cx": "50", "cy": "50", "r": "40",
        "stroke": "green", "stroke-width": "4", "fill": "yellow",
      ])
    }
  }
}

Arbitrary styles and scripts

While JavaScriptKit is a great option for occasional interactions with JavaScript, sometimes you need to inject arbitrary scripts or styles, which can be done through direct DOM access:

_ = document.head.object!.insertAdjacentHTML!("beforeend", #"""
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>
"""#)
_ = document.head.object!.insertAdjacentHTML!("beforeend", #"""
<link
  rel="stylesheet"
  href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css">
"""#)

This way both Semantic UI styles and moment.js localized date formatting (or any arbitrary style/script/font added that way) are available in your app.

Contributing

Modular structure

Tokamak is built with modularity in mind, providing a cross-platform TokamakCore module and separate modules for platform-specific renderers. Currently, the only available renderer module is TokamakDOM, but we intend to provide other renderers in the future, such as TokamakHTML for static websites and server-side rendering. Tokamak users only need to import a renderer module they would like to use, while TokamakCore is hidden as an "internal" Tokamak package target. Unfortunately, Swift does not allow us to specify that certain symbols in TokamakCore are private to a package, but they need to stay public for renderer modules to get access to them. Thus, the current workaround is to mark those symbols with underscores in their names to indicate this. It can be formulated as these "rules":

  1. If a symbol is restricted to a module and has no public access control, no need for an underscore.
  2. If a symbol is part of a public renderer module API (e.g. TokamakDOM), no need for an underscore, users may use those symbols directly, and it is re-exported from TokamakCore by the renderer module via public typealias.
  3. If a function or a type have public on them only by necessity to make them available in TokamakDOM, but unavailable to users (or not intended for public use), underscore is needed to indicate that.

The benefit of separate modules is that they allow us to provide separate renderers for different platforms. Users can pick and choose what they want to use, e.g. purely static websites would use only TokamakHTML, single-page apps would use TokamakDOM, maybe in conjuction with TokamakHTML for pre-rendering. As we'd like to try to implement a native renderer for Android at some point, probably in a separate TokamakAndroid module, Android apps would use TokamakAndroid with no need to be aware of any of the web modules.

Sponsorship

If this library saved you any amount of time or money, please consider sponsoring the work of its maintainer. While some of the sponsorship tiers give you priority support or even consulting time, any amount is appreciated and helps in maintaining the project.

Coding Style

This project uses SwiftFormat and SwiftLint to enforce formatting and coding style. We encourage you to run SwiftFormat within a local clone of the repository in whatever way works best for you either manually or automatically via an Xcode extension, build phase or git pre-commit hook etc.

To guarantee that these tools run before you commit your changes on macOS, you're encouraged to run this once to set up the pre-commit hook:

brew bundle # installs SwiftLint, SwiftFormat and pre-commit
pre-commit install # installs pre-commit hook to run checks before you commit

Refer to the pre-commit documentation page for more details and installation instructions for other platforms.

SwiftFormat and SwiftLint also run on CI for every PR and thus a CI build can fail with inconsistent formatting or style. We require CI builds to pass for all PRs before merging.

Code of Conduct

This project adheres to the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to [email protected].

Maintainers

Carson Katri, Jed Fox, Max Desiatov.

Acknowledgments

  • Thanks to the Swift community for building one of the best programming languages available!
  • Thanks to everyone who developed React with its reconciler/renderer architecture that inspired Tokamak in the first place.
  • Thanks to the designers of the SwiftUI API who showed us how to write UI apps in Swift declaratively (arguably even in a better way than React did).
  • Thanks to SwiftWebUI for reverse-engineering some of the bits of SwiftUI and kickstarting the front-end Swift ecosystem for the web.
  • Thanks to Render, ReSwift, Katana UI and Komponents for inspiration!

SwiftUI is a trademark owned by Apple Inc. Software maintained as a part of the Tokamak project is not affiliated with Apple Inc.

License

Tokamak is available under the Apache 2.0 license. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the LICENSE file for more info.

You might also like...
Managing Pull Requests and Issues For GitHub & GitHub Enterprise

Trailer For maintained binaries and/or more info: Latest macOS version Latest iOS version Trailer CLI for Mac, Linux and Windows Trailer for Android N

Aplicación SwiftUI para visualizar datos de Github dados un usuario y un token (Github token), implementa autenticación biométrica mediante FaceID.
Aplicación SwiftUI para visualizar datos de Github dados un usuario y un token (Github token), implementa autenticación biométrica mediante FaceID.

ios-app-swift-gitapp Aplicación SwiftUI para visualizar datos de Github dados un usuario y un token (Github token), implementa autenticación biométric

Xcode plugin to let you jump to GitHub History, Blame, PRs, Issues, Notifications of any GitHub repo with one shortcut.
Xcode plugin to let you jump to GitHub History, Blame, PRs, Issues, Notifications of any GitHub repo with one shortcut.

Reveal-In-GitHub Xcode plugin to let you jump to GitHub History, Blame, PRs, Issues, Notifications of current repo in one second. My company work on G

🏇 A Swift HTTP / HTTPS networking library just incidentally execute on machines
🏇 A Swift HTTP / HTTPS networking library just incidentally execute on machines

Thus, programs must be written for people to read, and only incidentally for machines to execute. Harold Abelson, "Structure and Interpretation of Com

Mockingbird was designed to simplify software testing, by easily mocking any system using HTTP/HTTPS
Mockingbird was designed to simplify software testing, by easily mocking any system using HTTP/HTTPS

Mockingbird Mockingbird was designed to simplify software testing, by easily mocking any system using HTTP/HTTPS, allowing a team to test and develop

CHIOTPField is a set of textfields that can be used for One-time passwords, SMS codes, PIN codes, etc. Mady by @ChiliLabs - https://chililabs.io
CHIOTPField is a set of textfields that can be used for One-time passwords, SMS codes, PIN codes, etc. Mady by @ChiliLabs - https://chililabs.io

CHIOTPField CHIOTPField is a set of textfields that can be used for One-time passwords, SMS codes, PIN codes, etc. All fields support insertion of one

A little and powerful iOS framework for intercepting HTTP/HTTPS Traffic.
A little and powerful iOS framework for intercepting HTTP/HTTPS Traffic.

A little and powerful iOS framework for intercepting HTTP/HTTPS Traffic.

A little and powerful iOS framework for intercepting HTTP/HTTPS Traffic.
A little and powerful iOS framework for intercepting HTTP/HTTPS Traffic.

A little and powerful iOS framework for intercepting HTTP/HTTPS Traffic from your app. No more messing around with proxy, certificate config. Features

Decode a string encoded in Base64 into an https link and launch it in Google Chrome

Decode a string encoded in Base64 into an https link and launch it in Google Chr

Joplin - an open source note taking and to-do application with synchronization capabilities for Windows, macOS, Linux, Android and iOS. Forum: https://discourse.joplinapp.org/
Joplin - an open source note taking and to-do application with synchronization capabilities for Windows, macOS, Linux, Android and iOS. Forum: https://discourse.joplinapp.org/

Joplin® is a free, open source note taking and to-do application, which can handle a large number of notes organised into notebooks. The notes are sea

Server-side Swift. The Perfect core toolset and framework for Swift Developers. (For mobile back-end development, website and API development, and more…)
Server-side Swift. The Perfect core toolset and framework for Swift Developers. (For mobile back-end development, website and API development, and more…)

Perfect: Server-Side Swift 简体中文 Perfect: Server-Side Swift Perfect is a complete and powerful toolbox, framework, and application server for Linux, iO

Server-side Swift. The Perfect core toolset and framework for Swift Developers. (For mobile back-end development, website and API development, and more…)
Server-side Swift. The Perfect core toolset and framework for Swift Developers. (For mobile back-end development, website and API development, and more…)

Perfect: Server-Side Swift 简体中文 Perfect: Server-Side Swift Perfect is a complete and powerful toolbox, framework, and application server for Linux, iO

Server-side Swift. The Perfect core toolset and framework for Swift Developers. (For mobile back-end development, website and API development, and more…)

Perfect: Server-Side Swift 简体中文 Perfect: Server-Side Swift Perfect is a complete and powerful toolbox, framework, and application server for Linux, iO

iOS project template with fastlane lanes, Travis CI jobs and GitHub integrations of Codecov, HoundCI for SwiftLint and Danger
iOS project template with fastlane lanes, Travis CI jobs and GitHub integrations of Codecov, HoundCI for SwiftLint and Danger

iOS project template This repository contains a template for iOS projects with a framework-oriented architecture approach, preconfigured fastlane lane

Swift implementation of Github REST API v3
Swift implementation of Github REST API v3

GitHubAPI Swift implementation of GitHub REST api v3. Library support Swift 4.2. Work is in progress. Currently supported: Issues API. Activity API(Fe

A Github's like work contribution timeline. 🤸🏻
A Github's like work contribution timeline. 🤸🏻

Workaholic 🤸🏻 A Github's like work contribution timeline. ToDo[s] Remove Dependancies of 3rd Party classes. You can watch to Workaholic to see conti

This is an example project of SwiftUI and Combine using GitHub API.
This is an example project of SwiftUI and Combine using GitHub API.

SwiftUI-Combine-Example This is an example project of SwiftUI and Combine using GitHub GET /search/users API. 📋 Requirements Swift5.1 Beta Xcode11.0

Sample iOS project built by SwiftUI + Flux and Combine framework using GitHub API
Sample iOS project built by SwiftUI + Flux and Combine framework using GitHub API

SwiftUI-Flux Flux enables us to have unidirectional data flow and make it testable. It's used to be implemented using RxSwift or ReactiveSwift in the

Owner
Max Desiatov
Software consultant, mostly coding for iOS and web in Swift and TypeScript. I co-maintain @SwiftWasm and @TokamakUI.
Max Desiatov
A library for building an internal/development support app easily

Scenarios A library supporting fast prototyping for iOS Projects. Introduction Challenges of mobile frontend development Stories with multiple require

An Tran 29 Sep 15, 2022
A simple and beautiful chart lib used in Piner and CoinsMan for iOS(https://github.com/kevinzhow/PNChart) Swift Implementation

PNChart-Swift PNChart(https://github.com/kevinzhow/PNChart) Swift Implementation Installation This isn't on CocoaPods yet, so to install, add this to

Kevin 1.4k Nov 7, 2022
Swift HTTP server using the pre-fork worker model

Curassow Curassow is a Swift Nest HTTP Server. It uses the pre-fork worker model and it's similar to Python's Gunicorn and Ruby's Unicorn. It exposes

Kyle Fuller Archive 397 Oct 30, 2022
Swift HTTP server using the pre-fork worker model

Curassow Curassow is a Swift Nest HTTP Server. It uses the pre-fork worker model and it's similar to Python's Gunicorn and Ruby's Unicorn. It exposes

Kyle Fuller Archive 397 Oct 30, 2022
Swift HTTP server using the pre-fork worker model

Curassow Curassow is a Swift Nest HTTP Server. It uses the pre-fork worker model and it's similar to Python's Gunicorn and Ruby's Unicorn. It exposes

Kyle Fuller Archive 397 Oct 30, 2022
MacBox - A fork of MacVM that fixes a bunch of UI issues

MacVM Fixes full screen problem by removing toolbar adding start stop to the men

heapwolf 9 Sep 8, 2022
Swift wrapper for Discord's API. Maintained fork of Azoy's Sword.

Sword - A Discord Library for Swift Requirements macOS, Linux, iOS, watchOS, tvOS (no voice for iOS, watchOS, or tvOS) At least Swift 5.3 Adding Sword

Sketch 38 Jan 3, 2023
Swiftcord - Swift wrapper for Discord's API. Maintained fork of Azoy's Sword

Swiftcord - A Discord Library for Swift Requirements macOS, Linux, iOS, watchOS,

Sketch 37 Nov 30, 2022
GraphQL-GitHub-Reader - Simple sample project that demonstrates how to connect with GitHub's API using GraphQL + Apollo

GHPViewer A beatiful way to see your GitHub Profile Installation The project is splitted in two folders: GHPViewer: Contains the iOS Application relat

Andrés Pesate 1 Jan 2, 2022
Github iOS Client based on Github REST V3 API and GraphQL V4 API

ZLGithubClient Github iOS 客户端 by Existorlive Objective-c 2.0 Swift 5 Cocoapods 1.9.1 iOS >= 11.0 基于 Github REST V3 API 和 Github GraphQL V4 API 开发的iOS客

朱猛 55 Dec 29, 2022