kabiroberai / node-swift

Create Node modules in Swift
MIT License
492 stars 16 forks source link

NodeSwift

Bridge Node.js and Swift code.

What is it?

NodeSwift allows you to write Swift code that talks to Node.js libraries, and vice versa. This enables possibilities such as

Example

MyModule.swift

import NodeAPI

#NodeModule(exports: [
    "nums": [Double.pi.rounded(.down), Double.pi.rounded(.up)],
    "str": String(repeating: "NodeSwift! ", count: 3),
    "add": try NodeFunction { (a: Double, b: Double) in
        "\(a) + \(b) = \(a + b)"
    },
])

index.js

const { nums, str, add } = require("./build/MyModule.node");
console.log(nums); // [ 3, 4 ]
console.log(str); // NodeSwift! NodeSwift! NodeSwift!
console.log(add(5, 10)); // 5.0 + 10.0 = 15.0

Features

How?

A NodeSwift module consists of an SwiftPM package and NPM package in the same folder, both of which express NodeSwift as a dependency.

The Swift package is exposed to JavaScript as a native Node.js module, which can be require'd by the JS code. The two sides communicate via Node-API, which is wrapped by the NodeAPI module on the Swift side.

Get started

For details, see the example in /example.

Alternatives

WebAssembly

While WebAssembly is great for performance, it still runs in a virtual machine, which means it can't access native Darwin/Win32/GNU+Linux APIs. NodeSwift runs your Swift code on the bare metal, which should be even faster than WASM, in addition to unlocking access to the operating system's native APIs.

On the other hand, if you want to run Swift code in the browser, WebAssembly might be the right choice since NodeSwift requires a Node.js runtime.

Other NAPI wrappers

NAPI, NAN, Neon etc. are all other options for building native Node.js modules, each with its own strengths. For example, NAPI is written in C and thus affords great portability at the cost of memory unsafety. NodeSwift is a great option if you want to enhance your JS tool on Apple platforms, if you want to bring Node.js code into your existing Swift program, or if you simply prefer Swift to C/C++/Rust/etc.