Express Tools - The Server Wizard 🚀

Strictly typed, production-ready, no-configuration server.
Express Tools allows you to build a conventional API server or a strictly typed server using Typed Bridge. It simplifies server development with minimal setup, making it easier to maintain type safety across the backend and frontend.
🌟 Key Features
- API Server: Production ready API server with 0 configuration.
- Typed Bridge: Strictly typed server functions tightly coupled with front-end.
📦 Installation
Install Express Tools via npm:
npm i express-tools
Build API Server
API server components:
- Express App:
const app = createApp()
- Server:
const server = startServer(app, 8080)
- Controller:
_c(async (args, context) => {})
- Validator: Request handler
_v({})
- Context middleware:
etConfig.contextParser = (req: Request) => { return {} }
Create express app & start server
import { createApp, startServer } from 'express-tools'
const app = createApp()
const server = startServer(app, 8080)
Test server: http://localhost:8080/health
Add new route
import { _c } from 'express-tools'
app.post(
'/demo',
_c(async (args: { id: number }) => {
console.log(args.id)
return { id: args.id, name: 'Express Tools' }
})
)
Validate request with zod
import { _c, $z } from 'express-tools'
const demoRequest = { id: $z.number().min(1) }
app.post(
'/demo',
_v({ id: $z.number().min(1) }),
_c(async (args: { id: number }) => {
return { id: args.id, name: 'Express Tools' }
})
)
Use ajv
or joi
validator
import { $a } from 'express-tools'
etConfig.validator = 'ajv'
import { $j } from 'express-tools'
etConfig.validator = 'joi'
Add context middleware
import { etConfig } from 'express-tools'
type context = {
name: string
authorization: string
}
etConfig.contextParser = (req: Request): context => {
const headers = req.headers
return { name: 'Express Tools', authorization: headers.authorization || 'NO_AUTH' }
}
app.post(
'/demo',
_v({ id: $z.number().min(1) }),
_c(async (args: { id: number }, context: context) => {
return { id: args.id, name: context.name }
})
)
Build Typed Bridge
Typed Bridge components:
- Bridge file: Main bridge file from which types are exported for front-end.
- Paths: Server function path like
user.fetch
, similar to routes. - Server functions: Actual server function which holds the business logic, similar to controller.
- Context parser: To provide context from request to server functions.
- Arguments: Server function arguments.
- Context: Server function context parsed with context parser.
Create express app & start server
server.ts
import { createApp, startServer } from 'express-tools'
const app = createApp()
const server = startServer(app, 8080)
Create Bridge
bridge/index.ts
import * as user from './user.bridge'
export default {
'user.fetch': user.fetch,
'user.update': user.update
}
bridge/user.bridge.ts
export const fetch = async (
args: { id: number },
context: { name: string; authorization: string }
): { id: number; name: string } => {
return { id: args.id, name: 'Express Tools' }
}
export const update = async () => {}
server.ts
import { createBridge } from 'express-tools'
app.use('/bridge', createBridge(bridge))
Call Typed Bridge functions from front-end
Generate typed bridge file
package.json
{
"scripts": {
"gen-typed-bridge": "express-tools gen-typed-bridge --src ./src/bridge/index.ts --dest ./typedBridge.ts"
}
}
src: Typed Bridge source file
dest: Output declaration file path
Import generated typedBridge.ts
file in front-end & call server functions.
import typedBridge from './typedBridge'
typedBridgeConfig.host = 'http://localhost:8080/bridge'
typedBridgeConfig.headers = { authorization: 'Basic mydemotoken==' }
..
const user = await typedBridge['user.fetch']({ id: 1 })
Generated Typed Bridge file can also be hosted publicly as it's doesn't contains any code, only the server functions schema. Every time front-end server started, it can be automatically synced using tools like clone-kit.
Express Tools config
import { etConfig } from 'express-tools'
etConfig.logs.request = true
etConfig.logs.requestData = false
etConfig.logs.response = true
etConfig.logs.error = true
etConfig.idPrefix = ''
etConfig.delay = 0
etConfig.validator = 'zod'
etConfig.contextParser = (req: Request) => {}
Developer
Developed & maintained by neilveil. Give a star to support my work.