Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ Full threat analysis in `spec/SECURITY-MODEL.md`.

| Decision | Rationale |
|---|---|
| **Go for the gateway** | Static compilation (CGO_ENABLED=0), zero runtime deps, ~3MB binary, `FROM scratch` compatible. No Node.js or bash needed in prod. |
| **Go for the gateway** | Static compilation (CGO_ENABLED=0), zero runtime deps, ~7MB binary, `FROM scratch` compatible. No Node.js or bash needed in prod. |

Copilot AI Feb 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The gateway size is updated to “~6MB” in multiple other docs in this PR, but CLAUDE.md says “~7MB”. This inconsistency can confuse readers; align all references to a single value, or use a small range (e.g., “~6–7MB depending on platform/build flags”) if the size varies by target/arch.

Suggested change
| **Go for the gateway** | Static compilation (CGO_ENABLED=0), zero runtime deps, ~7MB binary, `FROM scratch` compatible. No Node.js or bash needed in prod. |
| **Go for the gateway** | Static compilation (CGO_ENABLED=0), zero runtime deps, ~6–7MB binary depending on platform/build flags, `FROM scratch` compatible. No Node.js or bash needed in prod. |

Copilot uses AI. Check for mistakes.
| **Zero external Go dependencies** | Minimises supply chain risk. Only stdlib + crypto. Manifest parsing uses a hand-rolled YAML subset parser (~250 lines) to maintain this constraint. |
| **`pkg/payload` imports from `internal/`** | Valid Go — `internal/` rule only restricts imports from outside the parent directory tree. Both live under `gateway/`. |
| **`inject.go` strips `Accept-Encoding`** | Upstreams always respond with identity encoding, avoiding decompress/recompress. Gzip fallback via `compress/gzip` (stdlib) for non-compliant upstreams. Brotli unsupported (no stdlib, zero-dep constraint) — logged and passed through uninjected. |
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ WORKDIR /app
COPY . .
RUN npm ci && npm run build

# Add REP gateway — single binary, ~3MB
# Add REP gateway — single binary, ~6MB
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY --from=ghcr.io/ruachtech/rep/gateway:latest /usr/local/bin/rep-gateway /usr/local/bin/rep-gateway
Expand Down
2 changes: 1 addition & 1 deletion cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"ajv": "^8.12.0",
"js-yaml": "^4.1.0",
"dotenv": "^16.4.0",
"glob": "^10.3.0"
"glob": "^13.0.6"
},
"devDependencies": {
"typescript": "^5.4.0",
Expand Down
42 changes: 21 additions & 21 deletions docs/.astro/content-modules.mjs
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@

Copilot AI Feb 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs/.astro/* is typically build output for Astro and tends to churn (reordering/rewrites like in this diff). If this file is generated, it should generally be gitignored and removed from the repo to avoid noisy diffs and merge conflicts; if it’s intentionally committed, consider documenting why and how it should be updated to keep changes stable.

Suggested change
// NOTE: This file is generated by Astro's content collections build step.
// It is intentionally committed so that docs build output is available even
// in environments where running the Astro build is not possible.
// Do NOT edit this file by hand. To update it, run the docs build (for example:
// `npm run docs:build`) and commit the regenerated output.

Copilot uses AI. Check for mistakes.
export default new Map([
["src/content/docs/concepts/how-it-works.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fconcepts%2Fhow-it-works.mdx&astroContentModuleFlag=true")],
["src/content/docs/quick-start.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fquick-start.mdx&astroContentModuleFlag=true")],
["src/content/docs/concepts/security-model.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fconcepts%2Fsecurity-model.mdx&astroContentModuleFlag=true")],
["src/content/docs/contributing.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fcontributing.mdx&astroContentModuleFlag=true")],
["src/content/docs/quick-start.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fquick-start.mdx&astroContentModuleFlag=true")],
["src/content/docs/concepts/hot-reload.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fconcepts%2Fhot-reload.mdx&astroContentModuleFlag=true")],
["src/content/docs/concepts/variable-classification.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fconcepts%2Fvariable-classification.mdx&astroContentModuleFlag=true")],
["src/content/docs/concepts/wire-format.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fconcepts%2Fwire-format.mdx&astroContentModuleFlag=true")],
["src/content/docs/deployment/ci-cd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fdeployment%2Fci-cd.mdx&astroContentModuleFlag=true")],
["src/content/docs/contributing.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fcontributing.mdx&astroContentModuleFlag=true")],
["src/content/docs/deployment/docker-compose.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fdeployment%2Fdocker-compose.mdx&astroContentModuleFlag=true")],
["src/content/docs/index.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Findex.mdx&astroContentModuleFlag=true")],
["src/content/docs/concepts/hot-reload.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fconcepts%2Fhot-reload.mdx&astroContentModuleFlag=true")],
["src/content/docs/deployment/docker-embedded.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fdeployment%2Fdocker-embedded.mdx&astroContentModuleFlag=true")],
["src/content/docs/deployment/ci-cd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fdeployment%2Fci-cd.mdx&astroContentModuleFlag=true")],
["src/content/docs/deployment/docker-proxy.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fdeployment%2Fdocker-proxy.mdx&astroContentModuleFlag=true")],
["src/content/docs/deployment/docker-embedded.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fdeployment%2Fdocker-embedded.mdx&astroContentModuleFlag=true")],
["src/content/docs/examples/todo-react.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fexamples%2Ftodo-react.mdx&astroContentModuleFlag=true")],
["src/content/docs/deployment/kubernetes.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fdeployment%2Fkubernetes.mdx&astroContentModuleFlag=true")],
["src/content/docs/guides/installation.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Finstallation.mdx&astroContentModuleFlag=true")],
["src/content/docs/guides/development.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Fdevelopment.mdx&astroContentModuleFlag=true")],
["src/content/docs/guides/testing.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Ftesting.mdx&astroContentModuleFlag=true")],
["src/content/docs/frameworks/angular.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fframeworks%2Fangular.mdx&astroContentModuleFlag=true")],
["src/content/docs/guides/manifest.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Fmanifest.mdx&astroContentModuleFlag=true")],
["src/content/docs/frameworks/react.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fframeworks%2Freact.mdx&astroContentModuleFlag=true")],
["src/content/docs/frameworks/svelte.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fframeworks%2Fsvelte.mdx&astroContentModuleFlag=true")],
["src/content/docs/examples/quick-no-manifest.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fexamples%2Fquick-no-manifest.mdx&astroContentModuleFlag=true")],
["src/content/docs/examples/todo-react.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fexamples%2Ftodo-react.mdx&astroContentModuleFlag=true")],
["src/content/docs/frameworks/angular.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fframeworks%2Fangular.mdx&astroContentModuleFlag=true")],
["src/content/docs/frameworks/vanilla.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fframeworks%2Fvanilla.mdx&astroContentModuleFlag=true")],
["src/content/docs/examples/quick-no-manifest.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fexamples%2Fquick-no-manifest.mdx&astroContentModuleFlag=true")],
["src/content/docs/frameworks/vue.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fframeworks%2Fvue.mdx&astroContentModuleFlag=true")],
["src/content/docs/reference/codemod.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Freference%2Fcodemod.mdx&astroContentModuleFlag=true")],
["src/content/docs/reference/gateway-flags.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Freference%2Fgateway-flags.mdx&astroContentModuleFlag=true")],
["src/content/docs/reference/gateway-endpoints.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Freference%2Fgateway-endpoints.mdx&astroContentModuleFlag=true")],
["src/content/docs/guides/development.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Fdevelopment.mdx&astroContentModuleFlag=true")],
["src/content/docs/guides/installation.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Finstallation.mdx&astroContentModuleFlag=true")],
["src/content/docs/guides/testing.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Ftesting.mdx&astroContentModuleFlag=true")],
["src/content/docs/reference/cli.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Freference%2Fcli.mdx&astroContentModuleFlag=true")],
["src/content/docs/reference/codemod.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Freference%2Fcodemod.mdx&astroContentModuleFlag=true")],
["src/content/docs/guides/manifest.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Fmanifest.mdx&astroContentModuleFlag=true")],
["src/content/docs/reference/manifest-schema.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Freference%2Fmanifest-schema.mdx&astroContentModuleFlag=true")],
["src/content/docs/reference/sdk.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Freference%2Fsdk.mdx&astroContentModuleFlag=true")],
["src/content/docs/spec/security-model.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fspec%2Fsecurity-model.mdx&astroContentModuleFlag=true")],
["src/content/docs/spec/rfc-0001.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fspec%2Frfc-0001.mdx&astroContentModuleFlag=true")],
["src/content/docs/reference/gateway-endpoints.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Freference%2Fgateway-endpoints.mdx&astroContentModuleFlag=true")],
["src/content/docs/reference/gateway-flags.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Freference%2Fgateway-flags.mdx&astroContentModuleFlag=true")],
["src/content/docs/spec/conformance.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fspec%2Fconformance.mdx&astroContentModuleFlag=true")],
["src/content/docs/spec/index.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fspec%2Findex.mdx&astroContentModuleFlag=true")],
["src/content/docs/guides/migration/overview.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Fmigration%2Foverview.mdx&astroContentModuleFlag=true")],
["src/content/docs/guides/migration/from-next.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Fmigration%2Ffrom-next.mdx&astroContentModuleFlag=true")],
["src/content/docs/spec/rfc-0001.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fspec%2Frfc-0001.mdx&astroContentModuleFlag=true")],
["src/content/docs/spec/security-model.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fspec%2Fsecurity-model.mdx&astroContentModuleFlag=true")],
["src/content/docs/guides/migration/from-cra.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Fmigration%2Ffrom-cra.mdx&astroContentModuleFlag=true")],
["src/content/docs/guides/migration/from-vite.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Fmigration%2Ffrom-vite.mdx&astroContentModuleFlag=true")],
["src/content/docs/reference/adapters/vue.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Freference%2Fadapters%2Fvue.mdx&astroContentModuleFlag=true")],
["src/content/docs/guides/migration/overview.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Fmigration%2Foverview.mdx&astroContentModuleFlag=true")],
["src/content/docs/guides/migration/from-next.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Fmigration%2Ffrom-next.mdx&astroContentModuleFlag=true")],
["src/content/docs/reference/adapters/svelte.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Freference%2Fadapters%2Fsvelte.mdx&astroContentModuleFlag=true")],
["src/content/docs/reference/adapters/react.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Freference%2Fadapters%2Freact.mdx&astroContentModuleFlag=true")]]);
["src/content/docs/reference/adapters/react.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Freference%2Fadapters%2Freact.mdx&astroContentModuleFlag=true")],
["src/content/docs/reference/adapters/vue.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Freference%2Fadapters%2Fvue.mdx&astroContentModuleFlag=true")]]);

2 changes: 1 addition & 1 deletion docs/.astro/data-store.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/src/content/docs/deployment/docker-embedded.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ CMD ["--mode", "embedded", "--static-dir", "/static", "--port", "8080", "--stric

Exactly two things:
- Your built static files (`dist/`)
- The REP gateway binary (~3MB)
- The REP gateway binary (~6MB)

No OS, no shell, no utilities, no package manager. Attack surface: near zero.

Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/examples/todo-react.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,5 @@ The example uses a 3-stage multi-stage build:
3. **Final image:** `FROM scratch` with just the gateway binary and static files

<Aside type="tip">
The `FROM scratch` final image contains no OS, no shell, and no package manager. Total size is approximately 5MB (3MB gateway + 2MB static assets).
The `FROM scratch` final image contains no OS, no shell, and no package manager. Total size is approximately 8MB (6MB gateway + 2MB static assets).
</Aside>
2 changes: 1 addition & 1 deletion docs/src/content/docs/guides/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ npx @rep-protocol/cli dev --proxy http://localhost:5173

## Gateway binary

The gateway is a standalone Go binary (~3MB). There are several ways to get it:
The gateway is a standalone Go binary (~6MB). There are several ways to get it:

### Via the CLI (recommended)

Expand Down
8 changes: 4 additions & 4 deletions docs/src/content/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { Card, CardGrid, Tabs, TabItem } from '@astrojs/starlight/components';
<video controls playsinline preload="metadata" style="width: 100%; border-radius: 8px; border: 1px solid var(--sl-color-gray-5);">
<source src="https://github.com/RuachTech/rep/releases/download/v0.1.3/rep-gateway-demo.mp4" type="video/mp4" />
</video>
<p style="text-align: center; font-size: 0.85rem; color: var(--sl-color-gray-3); margin-top: 0.5rem;">Hot reload and feature flags — no rebuild, no redeploy.</p>
<p style="text-align: center; font-size: 0.85rem; color: var(--sl-color-gray-3); margin-top: 0.5rem;">Same frontend image, different environment, dynamic variables — no rebuild, no redeploy.</p>
</div>

## The Problem
Expand Down Expand Up @@ -68,7 +68,7 @@ REP operates at the **infrastructure layer** — no build-tool plugins, no frame

<CardGrid>
<Card title="Containers" icon="rocket">
Reverse proxy mode sits in front of nginx, caddy, or any upstream. Embedded mode serves static files directly from a `FROM scratch` image (~3MB).
Reverse proxy mode sits in front of nginx, caddy, or any upstream. Embedded mode serves static files directly from a `FROM scratch` image.
</Card>
<Card title="Static Builds" icon="document">
Build your app once with `npm run build`. The gateway injects config into the static HTML at serve time — same artifact for every environment.
Expand All @@ -89,7 +89,7 @@ REP operates at the **infrastructure layer** — no build-tool plugins, no frame
| Fetch `/config.json` at runtime | -- | -- | -- | -- | -- |
| `window.__ENV__` via shell script | -- | -- | -- | -- | -- |
| Build-tool plugins (dotenv, etc.) | -- | -- | -- | -- | -- |
| **REP** | **3-tier** | **AES-256-GCM** | **HMAC + SRI** | **SSE** | **~3MB Go** |
| **REP** | **3-tier** | **AES-256-GCM** | **HMAC + SRI** | **SSE** | **~6MB Go** |

## Quick Example

Expand Down Expand Up @@ -148,7 +148,7 @@ REP_SERVER_DB_PASSWORD=never-reaches-browser

<CardGrid>
<Card title="Gateway" icon="rocket">
Go binary (~3MB). Zero dependencies. `FROM scratch` compatible. Proxy or embedded mode.
Go binary (~6MB). Zero dependencies. `FROM scratch` compatible. Proxy or embedded mode.
</Card>
<Card title="SDK" icon="document">
TypeScript. Zero runtime deps. ~1.5KB gzipped. Synchronous `get()`, async `getSecure()`.
Expand Down
2 changes: 2 additions & 0 deletions examples/todo-react/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
dist
3 changes: 1 addition & 2 deletions examples/todo-react/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ WORKDIR /app

# Copy package files and install dependencies from npm registry.
COPY package.json ./
# install on main deps only,
RUN npm install --omit=dev
RUN npm install

Copilot AI Feb 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

npm install here is non-deterministic (especially since only package.json is copied), which can lead to irreproducible images and unexpected dependency drift. Prefer copying the lockfile(s) (e.g., package-lock.json) into the image and using npm ci for deterministic installs; if this stage needs devDependencies for the build, use npm ci (with dev deps) in the build stage and only omit/prune dev deps in the runtime stage (if applicable).

Copilot uses AI. Check for mistakes.

# Copy source and build.
COPY . .
Expand Down
4 changes: 2 additions & 2 deletions examples/todo-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"rep:serve": "rep dev --port 3000 --env .env.local --static ./dist --hot-reload"
},
"dependencies": {
"@rep-protocol/react": "^0.1.4",
"@rep-protocol/sdk": "^0.1.4",
"@rep-protocol/react": "^0.1.6",
"@rep-protocol/sdk": "^0.1.6",
"react": "^18.3.0",
"react-dom": "^18.3.0"
},
Expand Down
Loading
Loading