FAQ
Common questions about installation, TypeScript configuration, PostgreSQL, WebSockets, and deployment.
General
What is StreetJS Framework?
StreetJS is a production-grade TypeScript backend framework built entirely on Node.js core modules. It provides an HTTP server, router, dependency injection container, PostgreSQL driver, WebSocket server, security primitives, and a CLI — all without Express, pg, Prisma, or other heavy abstractions.
Why build another Node.js framework?
Most Node.js frameworks layer abstractions on top of abstractions. StreetJS takes the opposite approach: implement each component directly on Node.js core, enforce strict memory bounds, and expose a clean TypeScript API. The result is a framework where you can read and understand every line of the runtime.
Is StreetJS production-ready?
Yes. StreetJS is designed for production from the ground up — bounded memory, parameterized queries, SCRAM-SHA-256 PostgreSQL auth, AES-256-GCM sessions, and a comprehensive test suite including memory leak, wire protocol, load, fuzz, chaos, and security tests.
What are the two dependencies?
reflect-metadata— enables TypeScript’semitDecoratorMetadatafor constructor injectionws— WebSocket framing protocol (Node.jshttp.Serverhandles upgrades but not framing)
Everything else — HTTP, TLS, streams, crypto, cluster — ships with Node.js.
Installation
What Node.js version is required?
Node.js 20 or higher. StreetJS uses node:test, top-level await, crypto.randomUUID(), and other Node 20 APIs.
What TypeScript version is required?
TypeScript 5.0 or higher with NodeNext module resolution.
Do I need to install reflect-metadata separately?
Yes. Add it to your project:
1
npm install reflect-metadata
And import it as the first line of your entry point:
1
2
import 'reflect-metadata'; // must be first
import { streetApp } from 'streetjs';
Can I use StreetJS without the CLI?
Yes. Install streetjs directly and set up your project manually. The CLI (@streetjs/cli) is optional tooling.
TypeScript
Why does StreetJS require NodeNext module resolution?
NodeNext is the correct module resolution mode for Node.js ESM. It requires explicit .js extensions on imports, which matches how Node.js resolves modules at runtime. Other modes (bundler, node16) have subtle differences that cause issues in production.
Why do imports use .js extensions in .ts files?
This is required by NodeNext module resolution. TypeScript resolves .ts files when it encounters .js imports during compilation, but the compiled output uses .js — which is what Node.js needs at runtime.
1
2
// Correct — TypeScript resolves this to user.service.ts during compilation
import { UserService } from './user.service.js';
I’m getting error TS1240: Unable to resolve signature of class decorator
Add these to your tsconfig.json:
1
2
3
4
5
6
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
Database
Does StreetJS support databases other than PostgreSQL?
The built-in driver is PostgreSQL-only (wire protocol v3). For other databases, use the database’s official Node.js driver and register it manually with the container.
Do I need to install pg?
No. StreetJS implements the PostgreSQL wire protocol directly over node:net. There is no pg dependency.
How do I run migrations?
1
2
3
4
5
6
# Using the CLI
street migrate:create create_users_table
street migrate:run
# Or directly
node dist/main.js migrate
Does StreetJS support connection pooling?
Yes. PgPool manages a bounded pool of connections with idle timeout, acquire timeout, and automatic dead connection replacement.
Are queries safe from SQL injection?
Yes, when you use parameterized queries:
1
2
3
4
5
// Safe — parameterized
await pool.query('SELECT * FROM users WHERE id = $1', [userId]);
// Unsafe — never do this
await pool.query(`SELECT * FROM users WHERE id = '${userId}'`);
WebSockets
How do I limit WebSocket connections?
Pass maxConnections to StreetWebSocketServer:
1
const wss = new StreetWebSocketServer({ maxConnections: 10_000 });
Connections beyond the limit are rejected with close code 1013 (Try Again Later).
How do I authenticate WebSocket connections?
Pass a JWT token as a query parameter and validate it in the connection handler:
1
2
3
4
5
6
wss.on('connection', (socket, req) => {
const url = new URL(req.url!, 'http://localhost');
const token = url.searchParams.get('token');
if (!token) { socket.close(4001, 'Unauthorized'); return; }
// verify token...
});
Performance
How does StreetJS handle memory?
Every component has explicit bounds:
| Component | Bound |
|---|---|
| HTTP body | 1 MB default (configurable) |
| File uploads | Disk only — ≤128 KB heap |
| DB results | 256 rows buffered |
| LRU cache | maxEntries cap |
| Rate limiter | 100K IPs, 1K timestamps/IP |
| WebSocket connections | maxConnections |
Does StreetJS support clustering?
Yes. Use ClusterCoordinator to spawn worker processes:
1
2
3
4
import { ClusterCoordinator } from 'streetjs';
const coordinator = new ClusterCoordinator({ workers: 4 });
coordinator.start(() => bootstrap());
Deployment
Can I deploy StreetJS with Docker?
Yes. The generated Dockerfile uses a multi-stage build:
1
2
docker build -t my-api .
docker run -p 3000:3000 --env-file .env my-api
Does StreetJS work behind a reverse proxy (nginx, Caddy)?
Yes. Set HOST=0.0.0.0 and let the proxy handle TLS termination. Trust the X-Forwarded-For header for real IP detection in the rate limiter.
What environment variables are required in production?
At minimum:
NODE_ENV=productionJWT_SECRET— at least 32 random charactersSESSION_KEY— 64-character hex stringPG_HOST,PG_PORT,PG_DATABASE,PG_USER,PG_PASSWORD
Contributing
How do I report a bug?
Open an issue at github.com/hassanmubiru/issues with a minimal reproduction.
How do I contribute code?
See the Contributing Guide.
Is there a roadmap?
See the Roadmap.