AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified Apache-2.0 Self-run

Encore Service

skill-encoredev-skills-service · by encoredev

Plan how to split an Encore.ts application into services and lay out its directory structure. Architecture and decomposition, not first-time CLI install (that's `encore-getting-started`).

No reviews yet
0 installs
23 views
0.0% view→install

Install

$ agentstack add skill-encoredev-skills-service

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-encoredev-skills-service)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Encore Service? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Encore Service Structure

Instructions

Creating a Service

Every Encore service needs an encore.service.ts file:

// encore.service.ts
import { Service } from "encore.dev/service";

export default new Service("my-service");

Minimal Service Structure

my-service/
├── encore.service.ts    # Service definition (required)
├── api.ts               # API endpoints
└── db.ts                # Database (if needed)

Application Patterns

Single Service (Recommended Start)

Best for new projects - start simple, split later if needed:

my-app/
├── package.json
├── encore.app
├── encore.service.ts
├── api.ts
├── db.ts
└── migrations/
    └── 001_initial.up.sql

Multi-Service

For distributed systems with clear domain boundaries:

my-app/
├── encore.app
├── package.json
├── user/
│   ├── encore.service.ts
│   ├── api.ts
│   └── db.ts
├── order/
│   ├── encore.service.ts
│   ├── api.ts
│   └── db.ts
└── notification/
    ├── encore.service.ts
    └── api.ts

Large Application (System-based)

Group related services into systems:

my-app/
├── encore.app
├── commerce/
│   ├── order/
│   │   └── encore.service.ts
│   ├── cart/
│   │   └── encore.service.ts
│   └── payment/
│       └── encore.service.ts
├── identity/
│   ├── user/
│   │   └── encore.service.ts
│   └── auth/
│       └── encore.service.ts
└── comms/
    ├── email/
    │   └── encore.service.ts
    └── push/
        └── encore.service.ts

Service-to-Service Calls

Import other services from ~encore/clients:

import { user } from "~encore/clients";

export const getOrderWithUser = api(
  { method: "GET", path: "/orders/:id", expose: true },
  async ({ id }): Promise => {
    const order = await getOrder(id);
    const orderUser = await user.get({ id: order.userId });
    return { ...order, user: orderUser };
  }
);

When to Split Services

Split when you have:

| Signal | Action | |--------|--------| | Different scaling needs | Split (e.g., auth vs analytics) | | Different deployment cycles | Split | | Clear domain boundaries | Split | | Shared database tables | Keep together | | Tightly coupled logic | Keep together | | Just organizing code | Use folders, not services |

Service with Middleware

import { Service } from "encore.dev/service";
import { middleware } from "encore.dev/api";

const loggingMiddleware = middleware(
  { target: { all: true } },
  async (req, next) => {
    console.log(`Request: ${req.requestMeta?.path}`);
    return next(req);
  }
);

export default new Service("my-service", {
  middlewares: [loggingMiddleware],
});

Middleware Targeting

Control which endpoints middleware applies to:

// Apply to all endpoints
middleware({ target: { all: true } }, handler);

// Apply only to authenticated endpoints
middleware({ target: { auth: true } }, handler);

// Apply only to exposed (public) endpoints
middleware({ target: { expose: true } }, handler);

// Apply to raw endpoints only
middleware({ target: { isRaw: true } }, handler);

// Apply to streaming endpoints only
middleware({ target: { isStream: true } }, handler);

// Apply to endpoints with specific tags
middleware({ target: { tags: ["admin", "internal"] } }, handler);

Middleware Request Object

The request object provides access to:

const myMiddleware = middleware(
  { target: { all: true } },
  async (req, next) => {
    // For typed and streaming APIs
    const meta = req.requestMeta;  // { method, path, pathParams }

    // For raw endpoints
    const rawReq = req.rawRequest;
    const rawRes = req.rawResponse;

    // For streaming endpoints
    const stream = req.stream;

    // Custom data to pass to handlers
    req.data = { startTime: Date.now() };

    const resp = await next(req);

    // Modify response headers
    resp.header.set("X-Response-Time", `${Date.now() - req.data.startTime}ms`);

    return resp;
  }
);

Guidelines

  • Services cannot be nested within other services
  • Start with one service, split when there's a clear reason
  • Use ~encore/clients for cross-service calls (never direct imports)
  • Each service can have its own database
  • Service names should be lowercase, descriptive
  • Don't create services just for code organization - use folders instead

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.