# Aplikacje z kodu: SST vs Encore

> Dwa podejścia do App-as-Code: elastyczny framework IaC (SST) kontra konwencja z infrastrukturą wywiedzioną z kodu (Encore). Model, przykłady, wady i zalety.

URL: https://eiac.dev/blog/sst-vs-encore
Filar: App-as-Code
Data: 2026-05-15
Tagi: sst, encore, aws, typescript, app-as-code

---

Lubię takie porównania, bo dwa narzędzia obiecują dokładnie to samo, a pod maską są zupełnie inne. Obie platformy mówią: opisujesz aplikację w kodzie, a one ogarniają infrastrukturę pod spodem. Różni je jednak coś fundamentalnego — _skąd_ bierze się wiedza o tym, jaka infrastruktura jest potrzebna. [SST](/katalog/sst) każe Ci ją **zadeklarować** (elastycznie, jak w klasycznym IaC), [Encore](/katalog/encore) **wywodzi** ją z Twojego kodu aplikacji (przez analizę statyczną). To pozornie drobne rozróżnienie pociąga za sobą całą resztę: język, lock-in, sposób pracy lokalnej i to, ile decyzji musisz podjąć.

<div class="callout">
<strong>Oś sporu</strong>
<p>SST = <em>konfiguracja</em>: ty komponujesz zasoby z bloczków IaC. Encore = <em>konwencja</em>: framework czyta kod i sam dokłada infrastrukturę.</p>
</div>

## Czym jest SST

SST to framework do budowy i wdrażania pełnych aplikacji (frontend + backend + infrastruktura) — głównie na AWS. W wersji 3 jego silnikiem jest Pulumi z providerami Terraform, więc pod maską masz pełną moc klasycznego IaC: setki providerów i zasobów. Na wierzchu dostajesz wysokopoziomowe **komponenty** (`sst.aws.Function`, `sst.aws.Bucket`, `sst.aws.Astro` itd.), które ukrywają boilerplate, oraz mechanizm `link`, który automatycznie przekazuje uprawnienia i zmienne między zasobami.

Aplikację opisujesz w `sst.config.ts` — zwykłym TypeScript, z pętlami, warunkami i pakietami:

```ts
// sst.config.ts
export default $config({
  app: () => ({ name: "eiac", home: "aws" }),
  async run() {
    const bucket = new sst.aws.Bucket("Assets");

    const api = new sst.aws.Function("Api", {
      handler: "src/api.handler",
      url: true,
      link: [bucket], // nadaje funkcji dostęp do bucketa (IAM + env)
    });

    new sst.aws.Astro("Web", { link: [api] });

    return { api: api.url };
  },
});
```

Sygnaturą SST jest tryb `sst dev` — uruchamia lokalną pętlę developerską, w której kod funkcji działa na Twojej maszynie, ale jest wpięty w _prawdziwe_ zasoby w chmurze (tzw. Live Lambda). Dostajesz natychmiastowy feedback bez ciągłego deployu.

```bash
npx sst dev      # lokalny dev wpięty w realne zasoby w chmurze
npx sst deploy --stage production
```

Kluczowe cechy modelu SST:

- **Pełen IaC pod spodem** — przez Pulumi/Terraform sięgniesz po dowolny zasób (kolejki, bazy, DNS, Cloudflare), nie tylko gotowe komponenty.
- **Frontend i backend razem** — komponenty dla Next/Astro/React Router wdrażasz obok API w jednym repo.
- **`link` zamiast ręcznego IAM** — relacje między zasobami zamiast ręcznego klejenia uprawnień i zmiennych.
- **Stan i etapy (stages)** — odseparowane środowiska (`--stage`), stan trzymany jak w Pulumi.

## Czym jest Encore

Encore odwraca kierunek. Zamiast deklarować infrastrukturę, **deklarujesz elementy aplikacji** — serwisy, endpointy, bazy, kolejki, crony — jako konstrukcje w kodzie (TypeScript lub Go). Encore analizuje ten kod statycznie, buduje graf aplikacji i sam provisionuje potrzebne zasoby: lokalnie, a po wdrożeniu w chmurze. Infrastruktury nie opisujesz osobno — ona „wynika" z tego, czego użyłeś.

```ts
// api.ts — serwis, endpoint i baza wywiedzione z kodu
import { api } from "encore.dev/api";
import { SQLDatabase } from "encore.dev/storage/sqldb";

const db = new SQLDatabase("catalog", { migrations: "./migrations" });

export const getTool = api(
  { method: "GET", path: "/tools/:id", expose: true },
  async ({ id }: { id: string }) => {
    const row = await db.queryRow`SELECT name FROM tools WHERE id = ${id}`;
    return { tool: row?.name };
  },
);
```

Z deklaracji `new SQLDatabase(...)` Encore wie, że potrzebna jest baza — i tworzy ją sam (lokalnie w kontenerze, w chmurze jako zarządzaną instancję). Wywołania między serwisami są typowane: importujesz funkcję innego serwisu i wołasz ją jak zwykłą, a Encore zamienia to w wywołanie sieciowe z zachowaniem typów.

Drugą sygnaturą Encore jest lokalny dashboard: `encore run` startuje aplikację z **rozproszonym tracingiem, eksploratorem API i automatyczną dokumentacją** — bez konfiguracji.

```bash
encore run        # lokalnie: dashboard, tracing, API explorer
encore deploy     # wdrożenie (Encore Cloud) ...
encore build docker eiac:latest   # ... albo własny obraz do self-hostingu
```

Wdrożenie ma dwie drogi: **Encore Cloud** automatycznie provisionuje aplikację na Twoim koncie AWS/GCP (i daje CI/CD, środowiska, podgląd), albo budujesz samodzielny obraz Dockera (`encore build`) i uruchamiasz go gdziekolwiek, np. na [Kubernetes](/katalog/kubernetes).

Kluczowe cechy modelu Encore:

- **Infrastruktura z kodu** — brak osobnego IaC; zasoby wynikają z użytych prymitywów.
- **Konwencja zamiast konfiguracji** — mniej „kleju", więcej narzuconej struktury.
- **Wbudowana obserwowalność** — tracing, metryki, dokumentacja API od ręki.
- **Bezpieczne wywołania między serwisami** — typowane, sprawdzane w czasie kompilacji.

## Filozofia: konfiguracja kontra konwencja

To jest sedno różnicy. W SST infrastruktura jest **jawna i programowalna** — masz nad nią pełną kontrolę, ale też pełną odpowiedzialność: to Ty decydujesz, jaki zasób powołać i jak go połączyć. W Encore infrastruktura jest **domniemana** — framework wie, czego potrzebujesz, bo przeczytał Twój kod; płacisz za to dopasowaniem się do jego modelu.

Z tego wypływają wszystkie praktyczne konsekwencje: elastyczność kontra prostota, brak lock-inu na runtime kontra wbudowane „baterie", krzywa wejścia po stronie infrastruktury kontra krzywa wejścia po stronie konwencji frameworka.

## Te same zadania, dwa style

Spójrz na to samo zadanie — API z dostępem do magazynu danych — w obu narzędziach.

W **SST** najpierw deklarujesz zasób (`Bucket`), potem jawnie łączysz go z funkcją (`link`), a uprawnienia IAM i zmienne środowiskowe wygeneruje framework:

```ts
const bucket = new sst.aws.Bucket("Assets");
new sst.aws.Function("Api", { handler: "src/api.handler", link: [bucket] });
```

W **Encore** po prostu używasz prymitywu w kodzie — sama jego obecność „zamawia" infrastrukturę:

```ts
const bucket = new Bucket("assets", { public: false });
// użycie bucket.upload(...) w endpointcie wystarcza, by Encore go zapewnił
```

Różnica nie jest składniowa, lecz koncepcyjna: w SST infrastruktura to osobny, jawny obiekt; w Encore to efekt uboczny użycia API.

## Różnice w kluczowych wymiarach

| Wymiar               | SST                                    | Encore                                          |
| -------------------- | -------------------------------------- | ----------------------------------------------- |
| Model infrastruktury | deklarowana jawnie (komponenty)        | wywiedziona z kodu (analiza statyczna)          |
| Pod maską            | Pulumi + providerzy Terraform          | własny runtime + generowane IaC                 |
| Języki               | TypeScript/JavaScript                  | TypeScript i Go                                 |
| Chmura               | AWS-first (też Cloudflare i inne)      | AWS/GCP (Encore Cloud) lub własny obraz         |
| Frontend             | tak (Next/Astro/React…)                | nie (backend-first)                             |
| Lokalny DX           | `sst dev` (Live Lambda, realne zasoby) | `encore run` (dashboard, tracing, API explorer) |
| Obserwowalność       | dokładasz sam                          | wbudowana                                       |
| Elastyczność infry   | bardzo wysoka (cały IaC)               | ograniczona do modelu frameworka                |
| Lock-in              | na AWS/komponenty, nie na runtime      | na model i runtime Encore                       |
| Wyjście awaryjne     | naturalne (dropniesz do surowego IaC)  | węższe (poza modelem trudniej)                  |

## Wady i zalety

### SST

**Zalety**

- Pełna moc IaC — sięgniesz po dowolny zasób przez Pulumi/Terraform, nie tylko gotowce.
- Frontend + backend + infrastruktura w jednym repo i jednym wdrożeniu.
- `link` realnie redukuje boilerplate IAM i konfiguracji.
- Brak narzuconego runtime — Twój kod to zwykłe funkcje; mniejszy lock-in na sposób pisania.
- Świetny lokalny feedback (Live Lambda).

**Wady**

- AWS-centryczny — najlepiej działa na AWS; poza nim wsparcie jest węższe.
- Więcej decyzji i wiedzy o infrastrukturze po Twojej stronie.
- Trzeba zarządzać stanem i etapami (jak w Pulumi).
- Obserwowalność i konwencje musisz sobie poskładać sam.

### Encore

**Zalety**

- Minimum boilerplate — infrastruktura wynika z kodu, bez osobnego IaC.
- Wbudowana obserwowalność (tracing, metryki, dokumentacja API) od pierwszej minuty.
- Typowane, bezpieczne wywołania między serwisami.
- Spójna struktura w zespole dzięki konwencji.
- Elastyczne wdrożenie: Encore Cloud albo własny obraz Dockera.

**Wady**

- Lock-in na model i runtime Encore — wychodzisz poza schemat z trudem.
- Ograniczona elastyczność dla nietypowej infrastruktury.
- Tylko Go i TypeScript.
- Mniejszy ekosystem i społeczność niż wokół Pulumi/Terraform.
- „Magia" analizy statycznej bywa trudniejsza do debugowania, gdy coś nie zadziała.

## Kiedy co wybrać

- **Wybierz SST**, gdy potrzebujesz pełnej kontroli nad infrastrukturą AWS, chcesz wdrażać frontend razem z backendem albo sięgać po zasoby spoza „happy path" (kolejki, nietypowe usługi, multi-provider). Cena: więcej decyzji i wiedzy o IaC.
- **Wybierz Encore**, gdy budujesz backend/mikroserwisy i zależy Ci na maksymalnej prostocie, wbudowanej obserwowalności i szybkim starcie — a akceptujesz związanie z modelem frameworka. Cena: mniej elastyczności i lock-in na runtime.

Dobry papierek lakmusowy: jeśli najwięcej czasu spędzasz na _infrastrukturze_ i chcesz nią rządzić — SST. Jeśli najwięcej czasu spędzasz na _logice biznesowej_ i chcesz, żeby infrastruktura „po prostu była" — Encore.

## Podsumowanie

SST i Encore rozwiązują ten sam problem z dwóch przeciwnych stron. SST to elastyczny framework IaC z wysokopoziomowymi komponentami: dużo mocy, dużo kontroli, AWS w centrum. Encore to opinionowany framework backendowy, który infrastrukturę wywodzi z kodu i dorzuca obserwowalność: mało boilerplate'u, szybki start, w zamian za życie wewnątrz jego modelu.

Wybór sprowadza się do jednego pytania: czy chcesz **rządzić** infrastrukturą, czy chcesz o niej **zapomnieć**. Obie odpowiedzi są poprawne — pod warunkiem, że świadomie zaakceptujesz ich konsekwencje. U mnie? Zależy od projektu: do szybkiego backendu sięgam po Encore, do czegoś, co muszę wyrzeźbić po swojemu — po SST. Weź oba na warsztat na jednym weekendowym projekcie, różnicę poczujesz w pięć minut. :)