@spikard/node
v0.17.1
Published
Codegen-first polyglot web toolkit with a Rust core and bindings for 14 languages
Readme
Spikard — Part of the spikard polyglot web toolkit.
Codegen-first polyglot web toolkit on a Rust core: OpenAPI/AsyncAPI/GraphQL/JSON-RPC/gRPC codegen, SQL-to-HTTP, tower-http middleware, and an MCP server. Experimental, pre-1.0. Native NAPI-RS bindings for Node.js with TypeScript type definitions.
Install · Quick example · Features · Docs
[!IMPORTANT] spikard is experimental and pre-1.0. APIs change between releases and not every binding is at the same level of maturity, so it is not yet recommended for production. Feedback is genuinely wanted at this stage — open an issue if something is wrong, awkward, or missing.
What this package provides
Node.js-first TypeScript API — NAPI-RS native bindings with generated types and full async/await support
Type-safe routing — HTTP definitions with path, query, body, and header validation across all bindings
Spec-driven codegen — OpenAPI 3.0, AsyncAPI 3.0, GraphQL SDL, and JSON-RPC 2.0 support
Cross-language parity — same DTOs, fixtures, and error model prevent runtime drift
Tower middleware — compression, rate limiting, timeouts, auth (JWT/API key), static files
Lifecycle hooks —
onRequest,preValidation,preHandler,onResponse,onError
Installation
npm:
npm install @spikard/nodepnpm:
pnpm add @spikard/nodeyarn:
yarn add @spikard/nodeSystem Requirements
- Node.js 18+ required (NAPI-RS native bindings)
- Pre-built binaries for Linux (x86_64), macOS (arm64, x86_64), Windows (x86_64)
Quick example
import { App, ServerConfig } from "@spikard/node";
import { z } from "zod";
const UserSchema = z.object({ id: z.number(), name: z.string() });
type User = z.infer<typeof UserSchema>;
const app = new App();
app.get("/users/:id", async (req) => {
const id = Number(req.params["id"] ?? 0);
return { id, name: "Alice" };
});
app.post("/users", async (req) => {
const body = await req.json();
return UserSchema.parse(body);
});
if (require.main === module) {
app.config(new ServerConfig({ port: 8000 }));
app.run();
}Features
| Feature | Support | |---|---| | Type-safe routing | Path, query, body, and header parameter validation | | Request extraction | Typed structs for JSON, form data, multipart, and raw bodies | | Spec support | OpenAPI 3.0 · AsyncAPI 3.0 · GraphQL SDL · JSON-RPC 2.0 | | Middleware | Compression, rate limiting, timeouts, authentication, static files | | Lifecycle hooks | Request, pre-validation, pre-handler, response, and error hooks | | WebSocket & SSE | Bidirectional streams and server-sent events | | Error handling | Consistent error responses across all bindings via ProblemDetails | | Fixture testing | Shared JSON fixtures for behavioral consistency across languages |
import { Spikard, type Request } from "spikard";
import { z } from "zod";
const UserSchema = z.object({ id: z.number(), name: z.string() });
type User = z.infer<typeof UserSchema>;
const app = new Spikard();
const health = async (): Promise<{ status: string }> => ({ status: "ok" });
const createUser = async (req: Request): Promise<User> => {
return UserSchema.parse(req.json());
};
app.addRoute({ method: "GET", path: "/health", handler_name: "health", is_async: true }, health);
app.addRoute(
{
method: "POST",
path: "/users",
handler_name: "createUser",
request_schema: UserSchema,
response_schema: UserSchema,
is_async: true,
},
createUser,
);import { Spikard, type Request } from "spikard";
import { z } from "zod";
const PaymentSchema = z.object({
id: z.string().uuid(),
amount: z.number().positive(),
});
type Payment = z.infer<typeof PaymentSchema>;
const app = new Spikard();
const createPayment = async (req: Request): Promise<Payment> => {
return PaymentSchema.parse(req.json());
};
app.addRoute(
{
method: "POST",
path: "/payments",
handler_name: "createPayment",
request_schema: PaymentSchema,
response_schema: PaymentSchema,
is_async: true,
},
createPayment,
);import { Spikard, type Request } from "spikard";
const app = new Spikard();
app.onRequest(async (request: Request): Promise<Request> => {
console.log(`${request.method} ${request.path}`);
return request;
});Resources
- Repository — source code, examples, and issues
- Examples — working implementations in all supported languages
- Contributing — how to contribute
License
MIT License — see LICENSE for details.
