Experimental · pre-1.0

ANGULAR SERVER ARCHITECTURE

The server layer Angular was missing.

Strata brings Server Components to Angular and Analog: render components on the server, keep their code and dependencies out of the browser, and hydrate only the pieces that need interaction. When you need HTTP endpoints, structure them with Angular-native controllers.

Angular nativeAnalog + NitroServer Components preview

What Strata adds

Server ComponentsClient islandsControllers

Built on the stack you use

AngularAnalogNitroH3TypeScript

ExperimentalPreview

STRATA SERVER COMPONENTS

Angular components that stay on the server.

Server Components run Angular components on the server without shipping their implementation or server dependencies to the browser. Interactive children stay interactive: only explicit client boundaries hydrate.

This section’s module graph
ServerComponentsShowcaseServer Component server
ServerComponentFactsRepositoryInjected service server
server-component-proofTransitive import server
ServerComponentDemoClient island → browser
Shipped to the browser?
ServerComponentsShowcase server only
ServerComponentFactsRepository server only
server-component-proof server only
ServerComponentDemo browser

Live · rendered on the server

This panel is the proof.

Server Component
ServerComponentsShowcase
Implementation
server only
Data dependency
server only
Rendered by
Angular + Analog

Client island · hydrated in the browser

Props from the server: ServerComponentsShowcase with 3 server-only modules left behind.

Interactions: 0

Preview status. Currently dogfooded in this site and qualified in the repository on Node/Nitro and Cloudflare workerd. The public package is not released yet.

Navigation. The preview supports initial and document navigation. Angular Router SPA navigation into a new Server Component subtree is not supported yet.

SERVER PARENT, CLIENT ISLAND

One decorator, one explicit boundary.

Server ComponentClient boundary
product-summary.component.ts
import { Component, inject } from "@angular/core";
import { ServerComponent, StrataClientBoundary } from "@strata-sc/server-components";

import { AddToCartComponent } from "./add-to-cart.component";
import { ProductRepository } from "./product.repository";

@ServerComponent()
@Component({
  selector: "product-summary",
  imports: [AddToCartComponent, StrataClientBoundary],
  template: `
    <h1>{{ product.name }}</h1>
    <p>{{ product.description }}</p>

    <add-to-cart
      [productId]="product.id"
      [strataClient]="{ productId: product.id }"
    />
  `,
})
export class ProductSummary {
  // Server-only: neither this class nor ProductRepository
  // ever enters the browser bundle.
  private readonly products = inject(ProductRepository);

  protected readonly product = this.products.findById("42");
}
01Mark the parent server-only.

@ServerComponent() sits on an ordinary @Component. It renders with inject() on the server; the browser receives an empty surrogate.

02

Name what hydrates.

[strataClient] marks the child that ships. Its props cross as plain data: strings, numbers, booleans and null in a flat object.

03

Preview, not a package yet.

@strata-sc/server-components is private and experimental. It powers this page, but it is not published for installation.

ONE SERVER MODEL

Server-first, by construction.

Strata makes server-side Angular a coherent application model: server-rendered UI, explicit client islands and structured HTTP APIs, built on Angular primitives and the Analog/Nitro runtime.

Server-only by construction

Component implementations, repositories and server dependencies never enter the browser graph. The build swaps each Server Component for an empty surrogate.

See the module graph
Interactive where needed

Mark explicit client boundaries with [strataClient]. Only those Angular components hydrate, from plain-data props the server serialized.

See a client boundary
Structured APIs

Use Angular-native controllers when you need HTTP endpoints, registered on the Nitro router you already own.

See a controller

STRUCTURED APIs WHEN YOU NEED THEM

Controllers for the HTTP side.

users.controller.ts
import { Controller, Delete, Get, Patch, Post, Put } from "@strata-sc/core";
import type { StrataAnalogRequest } from "@strata-sc/analog";

@Controller("/api/users")
export class UsersController {
  @Get()
  list() {
    return [{ id: "1", name: "Ada" }];
  }

  @Post()
  async create(request: StrataAnalogRequest) {
    return request.readJson<{ name: string }>();
  }

  @Put("/:id")
  async replace(request: StrataAnalogRequest) {
    return { id: request.params["id"], ...(await request.readJson<{ name: string }>()) };
  }

  @Patch("/:id")
  async rename(request: StrataAnalogRequest) {
    const { name } = await request.readJson<{ name: string }>();
    return { id: request.params["id"], name };
  }

  @Delete("/:id")
  remove(request: StrataAnalogRequest) {
    return { deleted: request.params["id"] };
  }
}
01Start with your domain.

Controllers are ordinary classes. @Get, @Post, @Put, @Patch and @Delete create portable metadata with standard decorators, not a second application model.

02

Attach to a runtime when ready.

Register the class on Nitro's router from a server plugin with @strata-sc/analog. Native routes keep working beside it.

See the Analog integration

ANALOG, WITHOUT A DETOUR

Native to the Nitro seam.

The Analog adapter registers controllers where Nitro expects them: in a server plugin, on the router it already owns.

Analog pluginRoute metadata
src/server/plugins/strata.ts
import { registerControllers } from "@strata-sc/analog";
import { defineNitroPlugin } from "nitropack/runtime";
import { UsersController } from "../strata/users.controller";

export default defineNitroPlugin((nitroApp) => {
  registerControllers(nitroApp.router, [UsersController]);
});

TWO AXES, CLEAR OWNERSHIP

Strata never replaces your server.

It owns two precise seams: which parts of the UI graph stay on the server, and how controllers register on the router you already have. Angular, Analog and Nitro keep their lifecycles.

  • UI graph: Server Components and their dependencies stay server-side
  • Client boundaries are the only UI that hydrates
  • Controllers register on Nitro/H3; native routes stay
01Angular applicationComponents, routes and domain logic├─Server ComponentRendered on the server · server graph│ ├─Server dependencyRepositories, secrets · never shipped│ └─Client boundaryHydrated in the browser · plain-data props└─ControllerHTTP routes as metadata↓Analog / Nitro / H3Your owned request lifecycle

EARLY, OPEN, AND DELIBERATE

Build the next layer with us.

Strata is experimental today. Server Components are a private preview dogfooded on this site; controllers ship as 0.x releases. The design work is public and contributions are welcome.