Padawan (Getting Started)
Initialize
You can copy/paste the entire block below into a macOS/Linux/WSL terminal. It will:
- Install bun
- Create the project's directory
- Initialize the project
- Install all needed dependencies
- Install Mädūl
curl -fsSL https://bun.sh/install | bash
mkdir madul-example && cd $_
bun init -y
bun i @tsconfig/bun @tsconfig/node-lts bun-types
bun i @bsgbryan/madul
Why Bun?
Bun is an all-in-one toolkit for JavaScript and TypeScript apps. It ships as a single executable called bun
.
At its core is the Bun runtime, a fast JavaScript runtime designed as a drop-in replacement for Node.js. It's written in Zig and powered by JavaScriptCore under the hood, dramatically reducing startup times and memory usage.
The bun command-line tool also implements a test runner, script runner, and Node.js-compatible package manager, all significantly faster than existing tools and usable in existing Node.js projects with little to no changes necessary.
Read more at bun.sh
Your first Mädūl
Let's start small; over the following steps, you'll build a little Mädūl that does its best to greet people 😊
Configure
The items in "extends"
are not strictly required, but including them is good practice.
The compilerOptions.types
is also not required. We won't be doing anything in this tutorial that will need it, but as you build bigger and better Mädūls (specifically: Mädūls that use any of Bun's apis) having it will come in very handy.
The compilerOptions.paths
item is required to Mädūl to work. Below, you'll see "+Greeter"
- the compilerOptions.paths
item tells TypeScript where to find the Greeter
file we create.
{
"extends": [
"@tsconfig/bun/tsconfig.json",
"@tsconfig/node-lts/tsconfig.json"
],
"compilerOptions": {
"types": ["bun-types"],
"paths": {
"+*": ["./src/*"]
}
}
}
Define
Both code samples below are complete; they can be copy/pasted as-is into your project 😊
type OhaiInput = {
person: string
}
export const ohai = ({ person }: OhaiInput) => {
return `OHAI, ${person}, didn't see you there 😅`
}
Mädūl functions are just regular functions. All arguments are passed using an object. This is nice as it makes passing and using arguments easy and descriptive.
Test
import {
describe,
expect,
it,
} from "bun:test"
import greeter from "+Greeter"
describe('Greeter', () => {
it('greets a person', () => {
expect(typeof greeter.ohai).toBe('function')
expect(greeter.ohai({ person: 'Bryan' })).toBe("OHAI, Bryan, didn't see you there 😅")
})
})
Mädūl tests require no external tooling. There's nothing to get in your way when you're validating that your code behaves as required.
bun test
Use - via Bun's repl
$ bun repl
The code below does the following:
- Import Mädūl
- Instantiate the
greeter
Mädūl - Call function on the
greeter
Mädūl - Use returned value
import madul from "@bsgbryan/madul"
const greeter = madul('+Greeter')
const greeting = greeter.ohai({ person: 'Beth' })
console.log(greeting)
The console.log
statement above will display the following in your terminal:
OHAI Beth, I didn't see you there 😅