Quick start for Express
Add MainSDK to an Express app with one middleware and one error handler, guard a route with auth.require, run it in local mode and pass mainsdk check.
Status Status is where the work is: Planned (in a milestone, not started), Building (tickets in progress), Preview (usable, may change), then the stability it ships at.
Stability The promise an interface ships with.
- Stable Follows semantic versioning; breaking changes need a new major, 12 months of overlap and a codemod.
- Beta Usable in production; may change before it becomes stable.
- Experimental May change or go away; needs an explicit opt-in in main.yaml.
You will add MainSDK to an Express 5 app on Node.js 22 or later, guard one route and run it with no account or key. It takes about 10 minutes.
1. Initialise
npx mainsdk init2. Write the route
import { auth } from 'mainsdk'
// The route's logic is a plain Request in, Response out, so Express and a test call it the same way.
export async function me(req: Request): Promise<Response> {
const session = await auth.require(req) // 401 with a fix when nobody is signed in
return Response.json({ user: session.user })
}
// Express speaks Node requests, so hand the route a standard Request with the same headers.
export function toRequest(req: {
headers: Record<string, string | string[] | undefined>
originalUrl: string
}): Request {
const headers = new Headers()
for (const [name, value] of Object.entries(req.headers)) {
if (typeof value === 'string') headers.set(name, value)
}
return new Request(`http://${req.headers.host ?? 'localhost'}${req.originalUrl}`, { headers })
}3. Mount MainSDK
mainsdk() goes first and mainsdk.errors() goes last, so a thrown error becomes a problem response.
import express from 'express'
import { mainsdk } from 'mainsdk/express'
import { me, toRequest } from './routes.ts'
export const app = express()
app.use(mainsdk())
app.get('/me', async (req, res) => {
const out = await me(toRequest(req))
res
.status(out.status)
.type('application/json')
.send(await out.text())
})
app.use(mainsdk.errors()) // last: turns an error into a problem responseimport { app } from './app.ts'
app.listen(Number(process.env.PORT ?? 3000))4. Run it in local mode
In local mode the bearer token dev_ada stands for a test person called ada. It works only on loopback, under mainsdk dev.
npx mainsdk dev -- node --experimental-strip-types src/server.ts
curl -i localhost:3000/me
curl -i -H "Authorization: Bearer dev_ada" localhost:3000/meThe first call answers 401 with a problem body that carries MAIN-AUTH-0001 and a fix. The second answers 200 with the user.
Check it
npx mainsdk checkThe check passes when it prints Passed. It fails on a key in code, an undeclared network call or an unguarded action, and names the fix for each. Run it in CI too.
What the sample app is
The finished app is in the repository under apps/examples/express. CI installs it, starts it in local mode, requests the signed-in route and runs mainsdk check, so these steps cannot drift from the code. MainSDK is pre-release and no package is published yet: until the first beta, run the sample from a checkout.
Was this page helpful?