Use Bun with ReScript.
Use Bun with ReScript.
Template repo to get up and running quickly: https://github.com/zth/rescript-bun-starter
You need to be on ReScript v12 >=12.0.0-alpha.4.
Install rescript-bun:
``bash`
npm i rescript-bun@2
Include them in your rescript.json:
`json`
{
"dependencies": ["rescript-bun"]
}
rescript-bun is namespaced, so you'll find all modules listed under the main module RescriptBun.
You're strongly encouraged to open RescriptBun globally, to get the best possible developer experience. You do that by adding this to your rescript.json:
`json`
{
"bsc-flags": ["-open RescriptBun", "-open RescriptBun.Globals"]
}
> Notice -open RescriptBun.Globals. This will expose all Bun _globals_. This might be a matter of taste, but I recommend opening it to get the best experience.
This will make all of Bun available to you without needing to dip into the RescriptBun module explicitly.
This lib copies rescript-nodejs for Bun's Node compatible bindings. Shout out to the maintainers of that project!
Here's a few examples of how it looks. More examples (often inspired by https://bun.sh/guides) can be found in the playground/examples directory in this repo.
To write tests using Bun's built in test runner, just open Test and you'll have everything available to you to write your tests:
`rescript
open Test
describe("Playing around with tests", () => {
test("addition works", () => {
expect(1 + 1)->Expect.toBe(2)
})
})
`
This will make all of Bun's testing utilities available to you in the global scope.
Here's setting up a simple web server.
`rescript
let server = Bun.serve({
fetch: async (request, _server) => {
let userName =
request
->Request.headers
->Headers.get("x-user-name")
->Option.getOr("Unknown user")
Response.make(Hello ${userName}!, ~options={status: 200})
},
})
let port =
server
->Bun.Server.port
->Int.toString
let hostName = server->Bun.Server.hostname
Console.log(Server listening on http://${hostName}:${port}!)`
`rescript
let password = "super-secure-pa$$word"
let bcryptHash = await Bun.Password.hash(
password,
~algorithm=BCryptAlgorithm({
cost: 4, // number between 4-31
}),
)
let isMatch = await Bun.Password.verify(password, ~hash)
`
`rescript
let router = Bun.FileSystemRouter.make({
style: NextJs,
dir: "./pages",
origin: "https://mydomain.com",
assetPrefix: "_next/static/",
})
let matches = router->Bun.FileSystemRouter.match("/")
`
` let rewriter = HTMLRewriter.make()->HTMLRewriter.on( let response = await fetch("https://bun.sh") let html = await transformedResponse->Response.text Console.log(html) Currently, bindings exist for the most common things. There's still a good amount of bindings missing. Some bindings will be covered as we go along, while others won't be added. #### Crucial - [x] Globals #### Prio 2 - [x] AsyncHooks #### Prio 3 - [ ] FFI #### Unclear if needed - [x] Assert #### Definitively not needed - URL (available in globals) - How to reuse/contribute to rescript-webapi Contributions are very welcome. We're aiming to cover close to 100% of the Bun API surface, which is quite huge task. But, it's definitively possible and the initial large effort pays dividends over time. If you do want to contribute, _please open an issue saying you're starting work on module X_. So we don't accidentally double work. This project uses Changesets to manage versions and changelogs. Run npm run changeset _This will be fleshed out in a short while_.rescript
// Rewrite all to
"*",
{
element: element => {
if element.tagName === "div" {
element.tagName = "section"
}
},
},
)
let transformedResponse = rewriter->HTMLRewriter.transform(response)
`Current project state
$3
- [x] Bun
- [x] Tests
- [x] Fs
- [x] Stream (some stream utils already exist in Globals + Bun)
- [x] Path
- [x] Crypto
- [x] Buffer
- [x] Child_process (needs Stream?)
- [x] HTML Rewriter
- [x] Os
- [ ] Sqlite
- [x] Perf hooks
- [x] StringDecoder
- [x] Readline (needs Stream?)
- [x] WorkerThreads
- [x] Util
- [ ] SupportsColors
- [x] Timers
- [x] Tls
- [x] Tty
- [ ] Diagnostics channel
- [x] Dns
- [ ] Domain
- [x] Events
- [ ] JSC
- [x] Module
- [x] Net
- [x] VM
- [ ] WS (already multiple websocket things present)
- [x] Zlib (bun has its own gzip?)
- [x] Http (Nodes built in HTTP, should use Bun's own, right?)
- Constants (deprecated)
- Querystring (deprecated)
- Punycode (deprecated)
- Console (Core has it)Other things to figure out
instead of rolling our own bindings. I've intentionally not reused any other existing library because I wanted to start from scratch and follow ReScript v11+ idioms as much as possible. But once all of this settles, we need to figure out and share the common denominator with rescript-webapi and other similar projects to this.Contributing
Versioning and releasing
to create a changeset describing your changes. When changes are merged to main`, a GitHub Action opens a release PR and merging that will publish a new version.Bindings style