Quick Start
Build your first JustScale application in 5 minutes
Create a New Project
Bash
npx create-justscaleThe installer detects your package manager, IDE, and CI provider, then scaffolds a ready-to-run project. When it's done:
Bash
just dev๐ก
Tip
just is JustScale's CLI โ it's installed with @justscale/core and handles dev server, builds, tests, and plugin management.Create Your First Service
Services contain your business logic. Create src/services/greeting.ts:
Files
src/services/greeting.tsTypeScript
import { defineService } from '@justscale/core'
export class GreetingService extends defineService({
inject: {},
factory: () => ({
greet: (name: string) => `Hello, ${name}!`,
farewell: (name: string) => `Goodbye, ${name}!`,
}),
}) {}Create a Controller
Controllers group related routes. Create src/controllers/greeting.ts:
Files
src/controllers/greeting.tsTypeScript
import { createController } from '@justscale/core'
import { Get } from '@justscale/http'
import { z } from 'zod'
import { GreetingService } from '../services/greeting'
// Response schema for type safety & OpenAPI generation
const MessageResponse = z.object({
message: z.string(),
})
export const GreetingController = createController('/greet', {
inject: { greeting: GreetingService },
routes: (services) => ({
hello: Get('/:name')
.returns(200, MessageResponse)
.handle(({ params, res }) => {
const message = services.greeting.greet(params.name)
res.json({ message })
}),
goodbye: Get('/bye/:name')
.returns(200, MessageResponse)
.handle(({ params, res }) => {
const message = services.greeting.farewell(params.name)
res.json({ message })
}),
}),
})Create the Application
Wire everything together in src/index.ts:
Files
src/index.tsTypeScript
import JustScale from '@justscale/core'
import { defaultHttpConfig } from '@justscale/http/testing'
import { GreetingController } from './controllers/greeting'
import { GreetingService } from './services/greeting'
const app = JustScale()
.add(defaultHttpConfig)
.add(GreetingService)
.add(GreetingController)
.build()
await app.serve()
console.log('Server running on http://localhost:3000')Run It
Bash
just devTest your API:
Bash
curl http://localhost:6142/greet/World
# {"message":"Hello, World!"}
curl http://localhost:6142/greet/bye/World
# {"message":"Goodbye, World!"}What's Next?
Add Validation
Use Zod schemas to validate request body and declare response types:
users-controller.tsTypeScript
import { createController } from '@justscale/core';
import { Post } from '@justscale/http';
import { body } from '@justscale/http/builder';
import { z } from 'zod';
import { UserService } from './user-service';
const CreateUserBody = z.object({
email: z.string().email(),
name: z.string().min(2),
});
const UserResponse = z.object({
user: z.object({
email: z.string(),
name: z.string(),
}),
});
const UsersController = createController('/users', {
inject: { users: UserService },
routes: (services) => ({
create: Post('/')
.body(CreateUserBody)
.returns(201, UserResponse)
.handle(async ({ body, res }) => {
// body is typed as { email: string; name: string }
const user = await services.users.create(body);
res.status(201).json({ user });
}),
}),
});Add Models & Persistence
Define domain models with type-safe field builders and persist them with Repositories. In JustScale, models are pure domain objects โ no IDs or system fields in your code.
Add Features
Use Features for production-ready functionality like pub/sub channels, interactive shell, and more.