<!-- Markdown mirror of https://justscale.sh/docs/overview/quick-start -->

# Quick Start

Build your first JustScale application in 5 minutes

## Create a New Project

Bash

```bash
npx create-justscale
```

The installer detects your package manager, IDE, and CI provider, then scaffolds a ready-to-run project. When it's done:

Bash

```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

srccontrollersgreeting.ts

servicesgreeting.ts

index.ts

srccontrollersgreeting.ts

servicesgreeting.ts

index.ts

src/services/greeting.tsTypeScript

```typescript
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

srccontrollersgreeting.ts

servicesgreeting.ts

index.ts

srccontrollersgreeting.ts

servicesgreeting.ts

index.ts

src/controllers/greeting.tsTypeScript

```typescript
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

srccontrollersgreeting.ts

servicesgreeting.ts

index.ts

srccontrollersgreeting.ts

servicesgreeting.ts

index.ts

src/index.tsTypeScript

```typescript
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

```bash
just dev
```

Test your API:

Bash

```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

```typescript
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](https://justscale.sh/docs/models/overview) and persist them with [Repositories](https://justscale.sh/docs/repositories/overview). In JustScale, models are pure domain objects — no IDs or system fields in your code.

### Add Features

Use [Features](https://justscale.sh/docs/features/overview) for production-ready functionality like pub/sub channels, interactive shell, and more.

## Next Steps

- Services
- Controllers
- Models Overview
