| .github | ||
| src | ||
| tests | ||
| .gitignore | ||
| denim.nimble | ||
| LICENSE | ||
| README.md | ||
Denim - Native NodeJS/BunJS addons powered by Nim
👑 Written in Nim language
nimble install denim
API reference
😍 Key Features
- CLI build via Nim +
node-gypor CMake.js (faster) - CLI publish to NPM
- Low-level API
- High-level API
- Open Source |
MITLicense - Written in 👑 Nim language
Requirements
- Nim (latest / via
choosenim) - Node (latest) and
node-gypor CMake.js
CLI
Denim is a hybrid package, you can use it as a CLI for compiling Nim code to .node addon via Nim + NodeGYP and as a library for importing NAPI bindings.
Simply run denim -h
DENIM 🔥 Native Node/BunJS addons powered by Nim
build <entry> <links> --cmake --yes --verbose Build Nim project to a native NodeJS addon
publish Publish addon to NPM (requires npm cli)
Use Denim as a Nimble task:
task napi, "Build a .node addon":
exec "denim build src/myprogram.nim"
Want to pass custom flags to Nim Compiler? Create a .nims file:
when defined napibuild:
# add some flags
Note
Check fully-working examples in /tests
Defining a module
Use init to define module initialization.
when defined napibuild:
# optionally, you can use `napibuild` flag to wrap your code
# this flag is set when compiling via `denim build src/myprogram.nim`
import denim # import NAPI bindings
init proc(module: Module) =
# registering properties and functions here
# this is similar with javascript `module.exports`
elif isMainModule:
echo "just a normal nim program"
Nim Type to NapiValueType
Use low-level API to convert Nim values to napi_value (NapiValueType).
Use assert to check if a low-level function returns a success or failure. Currently, the following status codes are supported
import denim
init proc(module: Module) =
module.registerFn(0, "awesome"):
var str2napi: napi_value
var str = "Nim is awesome!"
assert Env.napi_create_string_utf8(str, str.len.csize_t, str2napi.addr)
return str2napi
Alternatively, use %* to auto-convert Nim values to NapiValueType.
let
a: napi_value = %* "Hey"
b: napi_value = %* true
assert a.kind == napi_string
assert b.kind == napi_boolean
Exports
Since v0.1.5, you can use {.export_napi.} pragma to export functions and object properties.
import denim
init proc(module: Module): # the name `module` is required
proc hello(name: string) {.export_napi} =
## A simple function from Nim
return %*("Hello, " & args.get("name").getStr)
var awesome {.export_napi.} = "Nim is Awesome!"
Calling a function/property from Node/Bun
const app = require('myaddon.node')
console.log(app.hello("World!")) // Hello, World!
console.log(app.awesome) // Nim is Awesome!
Built-in type checker
app.hello()
/*
* A simple function from Nim
* @param {string} name
* @return {string}
*/
Type mismatch parameter: `name`. Got `undefined`, expected `string`
Real-World Examples
- Tim Engine — A template engine. GitHub
- Bro — A fast stylesheet language, alternative to SassC, DartSass. GitHub
- HappyX — Macro-oriented asynchronous web-framework written in Nim. GitHub
Todo
- Option to link external C Headers/libraries
- Extend High-level API with compile-time functionality.
❤ Contributions & Support
- 🐛 Found a bug? Create a new Issue
- 👋 Wanna help? Fork it!
- 😎 Get €20 in cloud credits from Hetzner
🎩 License
Denim | MIT license. Made by Humans from OpenPeeps
Thanks to Andrew Breidenbach and Andrei Rosca for their work.
Copyright © 2023 OpenPeeps & Contributors — All rights reserved.