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

# Features

Pre-built feature modules for rapid application development

Features in JustScale are self-contained modules that bundle services, controllers, and configuration into reusable packages. They provide production-ready functionality that you can add to your application with a single import.

## What are Features?

A feature is a composable unit that encapsulates related functionality. Features can depend on other features, and JustScale automatically resolves and initializes them in the correct order.

src/app.tsTypeScript

```typescript
import JustScale from '@justscale/core';
import { ChannelFeature, MemoryChannelBackend } from '@justscale/core';
import { ShellFeature } from '@justscale/feature-shell';

const app = JustScale()
  .add(ShellFeature)
  .add(ChannelFeature)
  .add(MemoryChannelBackend)
  .build();

await app.serve({ http: 3000 });
```

## Feature Composition

Features compose cleanly and automatically integrate with each other. Features can declare dependencies on other features or abstract services, and JustScale validates these at build time.

### What Features Provide

- Services - Business logic and data access
- Controllers - HTTP endpoints and CLI commands
- Middleware - Request processing and guards
- Dependencies - Automatic resolution of required features

### Feature Benefits

- Plug-and-play - Add complete functionality with one import
- Type-safe - Dependencies validated at compile time
- Testable - Features can be tested in isolation
- Composable - Features work together seamlessly

## Available Features

### Authentication

The [AuthFeature](https://justscale.sh/docs/features/auth) ships built-in`User` and `Session` models, password hashing, and the `auth` middleware for route protection.

### Permissions

The [PermissionFeature](https://justscale.sh/docs/features/permissions) adds declarative, queryable access control — `permit().when()`rules live on the model and are used both as route guards and as automatic query filters.

### Channels (Pub/Sub)

The [ChannelFeature](https://justscale.sh/docs/fundamentals/channels) provides pub/sub messaging with async iterables. It requires an abstract backend that you can satisfy with MemoryChannelBackend or a Redis backend.

### Interactive Shell

The [ShellFeature](https://justscale.sh/docs/features/shell) provides an interactive REPL for your application. Think SSH, but you're connecting to the Node.js process itself to run commands and inspect state.

### Datastar (SSE)

The [Datastar integration](https://justscale.sh/docs/features/datastar) provides Server-Sent Events streaming and reactive signal management for real-time updates.

## Creating Custom Features

You can create your own features using `createFeatureBuilder`:

Files

srcfeaturesmy-feature.ts

app.ts

srcfeaturesmy-feature.ts

app.ts

src/features/my-feature.tsTypeScript

```typescript
import { createFeatureBuilder, defineService, createController } from '@justscale/core';
import { Get } from '@justscale/http';

class MyService extends defineService({
  inject: {},
  factory: () => ({
    getData: async () => ({ message: 'Hello from MyFeature!' }),
  }),
}) {}

const MyController = createController('/my-feature', {
  inject: { myService: MyService },
  routes: (services) => ({
    data: Get('/data').handle(async ({ res }) => {
      const data = await services.myService.getData();
      res.json(data);
    }),
  }),
});

export const MyFeature = createFeatureBuilder()
  .name('my-feature')
  .provides((b) => b
    .service(MyService)
    .controller(MyController)
  );
```

## Features with Dependencies

Features can declare dependencies on abstract services. The cluster builder validates that all dependencies are satisfied:

Files

srcfeaturesnotification-feature.tsemail-backend.ts

srcfeaturesnotification-feature.tsemail-backend.ts

src/features/notification-feature.tsTypeScript

```typescript
import { createFeatureBuilder, defineService, createAbstractServiceToken } from '@justscale/core';

// Abstract interface for notification backend
export const NotificationBackend = createAbstractServiceToken<{
  send: (userId: string, message: string) => Promise<void>;
}>('NotificationBackend');

class NotificationService extends defineService({
  inject: { backend: NotificationBackend },
  factory: ({ backend }) => ({
    notify: (userId: string, msg: string) => backend.send(userId, msg),
  }),
}) {}

export const NotificationFeature = createFeatureBuilder()
  .name('notification')
  .requires(NotificationBackend)  // Declares dependency
  .provides((b) => b.service(NotificationService));
```

## Next Steps

- Channels
- Shell Feature
- Datastar
