Getting Started
Install Silgi and build your first type-safe API in 5 minutes.
Install
bash npm install silgi zod bash pnpm add silgi zod bash bun add silgi zod You also need a validator. We use Zod here, but Valibot and ArkType also work.
What you will build
A small API with two endpoints:
users.list— returns a list of users (anyone can call it)users.create— creates a user (requires authentication)
Project structure
Two files. That's all you need to get started.
Step by step
Create the Silgi instance
This is where you tell Silgi how to build the context for each request. The context is an object that every procedure can access — a good place to put things like a database connection.
import { } from 'silgi'
const = ({
: () => ({
// This runs on every request.
// Whatever you return here is available as `ctx` in procedures.
: getDB(),
}),
})
// Export the helpers you need
export const { , , } =
export { }Define your procedures
A procedure is a single API endpoint. All procedures default to POST. Use .$route({ method: 'GET' }) for read-only endpoints.
import { , , } from './rpc'
import { } from 'silgi'
import { } from 'zod'
// A guard checks something before the procedure runs.
// If it returns an object, that object is added to the context.
const = (() => {
const = .headers?.authorization
if (!) throw new ('UNAUTHORIZED')
return { : 1 }
})
// A procedure with input validation
const = s.$input(.({ : .().(1).(100).() })).$resolve(({ , }) => {
return .db.users.findMany({ : .limit ?? 10 })
})
// A procedure that requires authentication
const =
.$use()
.$input(
.({
: .().(1),
: .().(),
}),
)
.$resolve(({ , }) => {
return .db.users.create({ ..., : .userId })
})Create a router and start the server
The router groups your procedures. The structure becomes the API path: users.list becomes /users/list.
// ... continuing from above
const = router({
: {
: listUsers,
: createUser,
},
})
s.serve(, {
: 3000,
: true, // Serves API docs at /reference
})Run it:
npx tsx src/server.tsYou should see:
Silgi server running at http://127.0.0.1:3000
Scalar API Reference at http://127.0.0.1:3000/referenceCall it from the client
import { } from 'silgi/client'
import { } from 'silgi/client/ofetch'
// The link tells the client how to talk to the server
const = ({ : 'http://localhost:3000' })
// InferClient gives you the types from the router
const = <any>()
// Now you have full autocomplete
const = await .users.list({ : 5 })
const = await .users.create({ : 'Alice', : '[email protected]' })In a real project, you would import the router type and use InferClient<typeof appRouter> instead of any. See the Client page for the full setup.
What's next?
Now that you have a working API, learn about the building blocks:
- Core Concepts — how context, guards, and wraps work together
- Procedures — the builder pattern for defining endpoints
- Server — serve(), handler(), HTTP/2, Scalar
- Client — ofetch link, binary mode, interceptors