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.
import { createClusterBuilder } from '@justscale/cluster';
import { ChannelFeature } from '@justscale/channel';
import { ShellFeature } from '@justscale/feature-shell';
import { InMemoryChannelBackend } from '@justscale/channel';
const cluster = createClusterBuilder()
.add(ShellFeature)
.add(ChannelFeature)
.add(InMemoryChannelBackend)
.build();
await cluster.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
Channels (Pub/Sub)
The ChannelFeature provides pub/sub messaging with async iterables. It requires an abstract backend that you can satisfy with InMemoryChannelBackend or a Redis backend.
Interactive Shell
The ShellFeature 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 provides Server-Sent Events streaming and reactive signal management for real-time updates.
Creating Custom Features
You can create your own features using createFeatureBuilder:
import { createFeatureBuilder, createService, createController } from '@justscale/core';
import { Get } from '@justscale/http';
const MyService = createService({
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:
import { createFeatureBuilder, createService, createAbstractServiceToken } from '@justscale/core';
// Abstract interface for notification backend
export const NotificationBackend = createAbstractServiceToken<{
send: (userId: string, message: string) => Promise<void>;
}>('NotificationBackend');
const NotificationService = createService({
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));