FastAPI for Node.js & Bun
β‘ 3.8x faster with Bun | π 89.3% of Fastify with Node.js
π¨ This is an ALPHA version and proof of concept. Do not use in production!
- β Core functionality works - Basic API creation, validation, and testing.
β οΈ API may change - Breaking changes are expected in future versions.β οΈ Not production-ready - Missing features, optimizations, and stability improvements.
- ErrorHandler - Dynamic Imports Compatibility: Fixed
instanceofparadox with dynamic imports inFluentAdapter.- Problem:
instanceofchecks fail across module boundaries when using dynamic imports - Solution: Implemented structural typing (NestJS-style) - check
statusCodeproperty first - Result: Works reliably with both regular imports AND dynamic imports
- Principle: SOLID - Depend on abstraction (statusCode) not implementation (instanceof)
- Problem:
-
File Uploads: Complete multipart/form-data support with validation.
@fastify/multipartintegrationFileValidatorfor size, mimetype, and extension validation- Multiple file uploads support
- Form fields + files parsing
- 7 E2E tests passing
-
Form Data: Full application/x-www-form-urlencoded support.
@fastify/formbodyintegration- Automatic parsing to
ctx.body - Works with Zod validation
- 10 E2E tests passing
-
Streaming & Buffer Responses: Raw data support for files and binary content.
- Stream responses (Node.js Readable)
- Buffer responses (binary data)
- Custom status codes + headers
- Validation bypass for streams
- 11 tests passing
-
Developer Experience: New testing tools for local/npm validation.
test-version.sh- Automated script for testing local vs npm versionsTEST-GUIDE.md- Complete testing workflow documentation- Workspace integration for
syntrojs-examples
- Tests: 647/647 passing (100% pass rate) β
- E2E Tests: 114 tests passing (100%) β
- Coverage: All new features fully tested
- Code Style: 100% SOLID + DDD + Functional programming
- v0.4.0 Progress: 60% complete (6/10 features done)
SyntroJS is the world's first dual-runtime framework that brings the simplicity and developer experience of FastAPI to the TypeScript ecosystem. Write your code once and run it on either Node.js for stability or Bun for maximum performance.
It's designed for developers who value verifiable quality, providing a powerful, integrated testing suite that makes writing high-quality, mutation-resistant tests as easy as building endpoints.
- π Dual Runtime Support: Write once, run on both Node.js and Bun with auto-optimization. Zero code changes required.
- π₯ FastAPI-like Developer Experience: Get automatic validation with Zod, full TypeScript type safety, and elegant error handling (
HTTPException). - π¨ Automatic Interactive Docs: Just like FastAPI, get a beautiful landing page and interactive Swagger UI + ReDoc documentation out of the box at
/docs. - π° TOON Format Support (Coming v0.5.0): First framework with hybrid JSON/TOON support. 40-60% payload reduction = massive cost savings for microservices. 1M tx/hour = $200-500/month saved in infrastructure costs. Game changer for high-scale APIs, LLMs, and mobile apps.
- π§ͺ The Testing Superpower: A uniquely powerful testing suite featuring
TinyTestfor effortless API testing, built-in boundary and contract testing, andSmartMutatorfor mutation testing in seconds, not hours. - π Rich Ecosystem: Includes a functional middleware system, WebSocket support, simple dependency injection, background tasks, and seamless integration with
@syntrojs/loggerfor structured logging. - π Security First: Production-ready configurations to easily disable documentation (
docs: false), plus built-in support for JWT, OAuth2, API Keys, and other security plugins.
npm install syntrojs zod
# or
pnpm add syntrojs zodCreate a fully documented and validated API in just a few lines.
import { SyntroJS } from 'syntrojs';
import { z } from 'zod';
const app = new SyntroJS({ title: 'My API' });
// A simple GET endpoint
app.get('/hello', { handler: () => ({ message: 'Hello World!' }) });
// A POST endpoint with automatic Zod validation
app.post('/users', {
body: z.object({
name: z.string().min(1),
email: z.string().email(),
}),
handler: ({ body }) => ({ id: 1, ...body }),
});
await app.listen(3000);That's it! π Visit http://localhost:3000 for the welcome page or http://localhost:3000/docs for your interactive API documentation.
SyntroJS automatically detects your runtime and optimizes accordingly. The exact same code delivers the best of both worlds: stability on Node.js and extreme speed on Bun.
// app.js
import { SyntroJS } from 'syntrojs';
const app = new SyntroJS({ title: 'My API' });
app.get('/runtime', {
handler: () => ({
runtime: typeof Bun !== 'undefined' ? 'Bun (JavaScriptCore)' : 'Node.js (V8)',
performance: typeof Bun !== 'undefined' ? '3.8x faster than Fastify' : '89.3% of Fastify'
})
});
await app.listen(3000);Run with Node.js for stability:
node app.js
# π SyntroJS-NODE | Running on Node.js (V8)
# Performance: 89.3% of FastifyRun with Bun for maximum performance:
bun app.js
# π SyntroJS-BUN | Running on Bun (JavaScriptCore)
# Performance: 3.8x faster than Fastify| Runtime | Performance | Use Case |
|---|---|---|
| Node.js | 89.3% of Fastify | Production stability, full ecosystem |
| Bun | 3.8x faster than Fastify | Maximum performance, modern development |
SyntroJS believes testing should be a first-class citizen, not an afterthought. We make writing high-quality, verifiable tests as easy as creating the endpoints themselves.
TinyTest mirrors the SyntroJS API, so writing a test feels just like defining a route. It manages the server lifecycle for you.
import { TinyTest } from 'syntrojs/testing';
import { z } from 'zod';
test('POST /users creates a user successfully', async () => {
const api = new TinyTest();
api.post('/users', {
body: z.object({ name: z.string(), email: z.string().email() }),
handler: ({ body }) => ({ id: 1, ...body }),
});
const { status, data } = await api.expectSuccess('POST', '/users', {
body: { name: 'John', email: 'john@example.com' }
});
expect(status).toBe(201); // Or your desired status
expect(data.name).toBe('John');
await api.close();
});Mutation testing tools often create "mutants" by changing things like .min(18) to .min(17). Most tests won't catch this. SyntroJS provides testBoundaries to automatically test these exact edge cases, ensuring your validation logic is robust.
// This test kills mutants that other tests miss!
test('POST /users validates age boundary', async () => {
const api = new TinyTest();
api.post('/users', {
body: z.object({ age: z.number().min(18) }), // Must be 18+
handler: ({ body }) => ({ ...body }),
});
// Automatically tests the edges of your validation
await api.testBoundaries('POST', '/users', [
{ input: { body: { age: 17 } }, expected: { success: false } }, // β Must fail
{ input: { body: { age: 18 } }, expected: { success: true } }, // β
Must pass
]);
await api.close();
});Traditional mutation testing with Stryker can take 30-60 minutes, making it unusable for daily development. SmartMutator, our optimized runner, gives you the same results in seconds.
| Method | Mutants | Tests Executed | Time |
|---|---|---|---|
| Stryker (vanilla) | 1,247 | 187,050 | 43 min |
| SmartMutator | 142 | 284 | 12 sec |
| SmartMutator (incremental) | 8 | 16 | 3.2 sec |
This transforms mutation testing from a slow CI/CD step into a real-time quality feedback tool you can run every time you save a file.
# Run lightning-fast mutation testing
pnpm test:mutateThe SyntroJS Guarantee: We're the only framework where writing high-quality, mutation-resistant tests is a core, integrated part of the developer experience.
For production deployments, security is critical. SyntroJS makes it easy to lock down your application.
ALWAYS disable documentation in production:
const app = new SyntroJS({
title: 'Production API',
docs: false // β
REQUIRED for production
});- Disable all documentation (
docs: false) - Set proper CORS origins (not
*) - Enable rate limiting
- Configure structured logging without sensitive data (
@syntrojs/logger). - Use environment variables for secrets.
For production-ready examples, including microservices, benchmarks, and security patterns, see our dedicated Examples Repository.
SyntroJS follows Domain-Driven Design (DDD) and SOLID principles to ensure a clean, maintainable, and testable codebase. Key design principles include Simplicity, Type-Safety, and Quality First.
For a deeper dive, see our ARCHITECTURE.md document.
HTTP Methods
- β GET, POST, PUT, PATCH, DELETE
- β HEAD
- β OPTIONS
- β WebSockets
Request Handling
- β Path parameters with Zod validation
- β Query parameters with Zod validation
- β JSON body with Zod validation
- β Headers
- β Cookies
Response Handling
- β JSON responses (default)
- β HTML responses (string)
- β Custom status codes
- β Custom headers
- β Streaming responses (Node.js Readable)
- β Buffer responses (binary data)
- π TOON responses (40-60% payload reduction - game changer for microservices & LLMs)
Validation & Error Handling
- β Automatic Zod validation
- β HTTPException with custom errors
- β Error handlers per route
- β Pagination helpers
- β Sorting helpers
Security & Middleware
- β CORS plugin
- β Helmet (security headers)
- β Rate limiting
- β Compression
- β Bearer token auth (HTTPBearer, OAuth2PasswordBearer)
- β API Key auth (header, query, cookie)
- β HTTP Basic auth
- β Global & route-specific middlewares
Developer Experience
- β Automatic OpenAPI/Swagger documentation
- β Interactive API docs (Swagger UI + ReDoc)
- β Beautiful landing page
- β Route groups
- β Dependency injection
- β Background tasks
- β Dual runtime (Node.js + Bun)
- β TinyTest for easy testing
- β SmartMutator for mutation testing
HTTP Methods (Quick Wins)
- HEAD method -
.head()public method β - OPTIONS method -
.options()public method β - Auto-OPTIONS for CORS preflight β
File Handling (High Priority)
- Streaming responses - For large files β v0.4.0-alpha.1
- File downloads - Helper for
Content-Dispositionheaders - Static file serving - Expose
@fastify/staticintegration - File uploads - Multipart form data support (
@fastify/multipart) β v0.4.0-alpha.1
Request Body Formats
- JSON (default) β
- Form data (
application/x-www-form-urlencoded) β v0.4.0-alpha.1 - Multipart form data (
multipart/form-data) β v0.4.0-alpha.1 - Raw text/binary support β v0.4.0-alpha.1 (Buffer responses)
- TOON (
application/toon) - 40-60% smaller payloads (microservices, LLMs, mobile) - XML body parsing
Response Types
- JSON (default) β
- TOON - Content negotiation for payload efficiency (40-60% reduction = cost savings)
- Redirects (301, 302, 307, 308) -
.redirect()helper - XML responses
- File download responses β v0.4.0-alpha.1 (Streaming + Buffer support)
HTTP Features
- Content negotiation (Accept headers)
- ETags / Cache headers
- Partial responses (Range headers)
- Conditional requests (If-Modified-Since, If-None-Match)
TOON Format Support (New! π― Game Changer for Microservices)
-
Hybrid REST API - JSON by default, TOON on demand
- Parse requests with
Content-Type: application/toon - Respond with TOON based on
Accept: application/toonheader - Automatic content negotiation (transparent to business logic)
- 40-60% payload reduction vs JSON
- Integration with @toon-format/toon
- Parse requests with
-
Use Cases & ROI:
- Microservices: 1M tx/hour = 720GB/month saved = $200-500/month infrastructure cost reduction
- LLM APIs: 40-60% token cost reduction (OpenAI, Claude, etc.)
- High-frequency APIs: Lower latency, less CPU overhead
- Mobile apps: Reduced data usage for users
- IoT: Minimal bandwidth for embedded devices
-
Implementation:
- Content negotiation with
Acceptheader - Benchmarks: TOON vs JSON (payload size, parse time, serialize time)
- Documentation with cost-benefit analysis
- Real-world examples (microservices, LLM prompts, mobile apps)
- Content negotiation with
Security
- CSRF protection
- Session management (
@fastify/session) - Cookie-based authentication
- JWT refresh tokens
- OAuth2 flows (authorization code, client credentials)
Real-time Communication
- Server-Sent Events (SSE)
- WebSocket rooms/namespaces
- WebSocket authentication
- WebSocket middleware
Template & Views
- Template rendering (
@fastify/view) - Support for major engines (EJS, Pug, Handlebars)
- Layouts and partials
Database Integration
- ORM adapters (Prisma, TypeORM, Drizzle)
- ODM adapters (Mongoose)
- Query builder integration
- Transaction support
- Database migrations helper
API Features
- GraphQL support
- API versioning
- Request/Response transformation hooks
- Custom serializers
- Response compression strategies
Developer Tools
- Official CLI (
create-syntrojs) - Code generation for CRUD
- Migration tools from Express/Fastify
- VSCode extension
- Debug tools
Production Features
- Graceful shutdown
- Health checks endpoint
- Metrics/Prometheus integration
- Distributed tracing (OpenTelemetry)
- Load balancing helpers
- Clustering support
Documentation
- Comprehensive guides
- Video tutorials
- Recipe book
- Migration guides
- Best practices guide
- Performance tuning guide
| Feature | Status | Priority | Target Version |
|---|---|---|---|
| HEAD method | β Done | High | v0.3.13 |
| OPTIONS method | β Done | High | v0.3.13 |
| Streaming responses | β Done | High | v0.4.0-alpha.2 |
| File uploads | β Done | High | v0.4.0-alpha.2 |
| Form data | β Done | Medium | v0.4.0-alpha.2 |
| Buffer responses | β Done | Medium | v0.4.0-alpha.2 |
| File downloads | π΄ Missing | High | v0.4.0 |
| Static files | π‘ Partial | High | v0.4.0 |
| Redirects | π΄ Missing | High | v0.4.0 |
| Content negotiation | π΄ Missing | Medium | v0.4.0 |
| ETags | π΄ Missing | Medium | v0.4.0 |
| SSE | π΄ Missing | Medium | v0.5.0 |
| CSRF | π΄ Missing | Medium | v0.5.0 |
| Sessions | π΄ Missing | Medium | v0.5.0 |
| Templates | π΄ Missing | Low | v0.5.0 |
| GraphQL | π΄ Missing | Low | v1.0.0 |
| ORM integration | π΄ Missing | Low | v1.0.0 |
Add HEAD method- β Done (v0.3.13)Add OPTIONS method- β Done (v0.3.13)Auto-OPTIONS for CORS- β Done (v0.3.13)Streaming responses- β Done (v0.4.0-alpha.1)File uploads- β Done (v0.4.0-alpha.1) - Multipart/form-data with FileValidatorForm data support- β Done (v0.4.0-alpha.1) - application/x-www-form-urlencoded- File downloads helper - 2 days (Content-Disposition headers)
- Static file serving - 2 days (@fastify/static integration)
- Redirect helper - 1 day (301, 302, 307, 308)
- Content negotiation - 2 days (Accept headers)
Total estimate: ~2 weeks (6/10 completed - 60% β )
Completed in alpha releases:
- β HEAD & OPTIONS methods (v0.3.13)
- β Streaming responses + Buffer support (v0.4.0-alpha.1)
- β File uploads with validation (v0.4.0-alpha.1)
- β Form data parsing (v0.4.0-alpha.1)
- β ErrorHandler fix for dynamic imports (v0.4.0-alpha.2)
We welcome contributions! Check out our GitHub repository for details on how to contribute.
Apache 2.0 - See LICENSE for details.