Skip to content

feat: add Deno deployment adapter - #194

Open
rturnq wants to merge 5 commits into
mainfrom
claude/deno-adapter
Open

feat: add Deno deployment adapter#194
rturnq wants to merge 5 commits into
mainfrom
claude/deno-adapter

Conversation

@rturnq

@rturnq rturnq commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a new adapter package, @marko/run-adapter-deno, for previewing and deploying Marko Run apps to Deno and Deno Deploy.

  • SSR target webworker with the deno export condition and noExternal: true, so the build produces a single self-contained server entry at dist/index.js.
  • The entry serves the app via Deno.serve and, when no route matches, falls back to serving static files from dist/public — with immutable caching for /assets/*, a content-type lookup, and a path-traversal guard. It listens on the PORT environment variable (default 3000).
  • Because the output is self-contained, it runs anywhere Deno does (deno run --allow-net --allow-read --allow-env dist/index.js) and deploys to Deno Deploy by pointing the entrypoint at dist/index.js (e.g. deployctl deploy --entrypoint=dist/index.js).
  • Route handlers receive the Deno.serve request info (including remoteAddr) via the exported DenoPlatformInfo type.

Also adds a test fixture to the @marko/run package (deno-adapter) mirroring the existing adapter fixtures, and a changeset for the new package.

Motivation and Context

Deno and Deno Deploy are a natural target for Marko Run since the runtime is built on web standards, but no adapter existed. This provides a zero-config build that runs on the Deno CLI and deploys to Deno Deploy, alongside the existing Node, static, and Netlify adapters.

Screenshots (if appropriate):

Checklist:

  • I have updated/added documentation affected by my changes.
  • I have added tests to cover my changes.

Generated by Claude Code

Add @marko/run-adapter-deno for deploying Marko Run apps to Deno and
Deno Deploy.

- SSR target webworker with the deno export condition; the build produces
  a self-contained dist/index.js
- The entry serves the app via Deno.serve and falls back to serving static
  assets from dist/public (with immutable caching for /assets and a path
  traversal guard), listening on the PORT env var
- Exposes the request info (remoteAddr) to handlers via DenoPlatformInfo
- Adds a run-package test fixture (preview skipped; it needs the Deno CLI)
@changeset-bot

changeset-bot Bot commented Jun 30, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8282016

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@marko/run-adapter-deno Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a54666e1-6193-479b-b650-b28db00606a2

📥 Commits

Reviewing files that changed from the base of the PR and between 95fcdd4 and 8282016.

📒 Files selected for processing (1)
  • packages/adapters/deno/README.md
✅ Files skipped from review due to trivial changes (1)
  • packages/adapters/deno/README.md

Walkthrough

This PR adds a new @marko/run-adapter-deno package for running Marko Run apps on Deno and Deno Deploy. It introduces the Deno platform type, a Deno.serve entry that serves router responses and static assets, adapter hooks for Vite build/preview/dev behavior, build and package metadata, README documentation, a changeset, and a Deno adapter test fixture with generated route typings and sample interactions.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly names the main change: adding a Deno deployment adapter.
Description check ✅ Passed The description matches the PR scope, covering the new Deno adapter, docs, tests, and changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/deno-adapter

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
packages/adapters/deno/package.json (1)

23-26: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Empty test script.

No tests are wired up for this package. Given the README's documented DenoPlatformInfo/static-serving behaviors, at least minimal unit coverage of buildEnd's renaming logic or viteConfig's SSR options would help guard against regressions. Not blocking given the existing fixture-based integration test in packages/run.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/adapters/deno/package.json` around lines 23 - 26, The package
currently has an empty test script, so wire up a real test command in the
scripts section and add at least minimal unit coverage for the Deno adapter.
Focus on the uniquely named entry points `buildEnd` and `viteConfig`, covering
the renaming behavior and SSR/static-serving options described by
`DenoPlatformInfo` so regressions are caught even if line numbers shift.
packages/adapters/deno/scripts/build.ts (1)

40-44: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

splitting: true has no effect with a single entry point.

Code-splitting only kicks in with multiple entry points or dynamic imports across them; here entryPoints is just ["src/index.ts"], so this flag is currently a no-op. Harmless, but consider removing for clarity unless splitting across default-entry.ts/index.ts is intended (in which case both would need to be in the same entryPoints array).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/adapters/deno/scripts/build.ts` around lines 40 - 44, The build
configuration in build() is setting splitting: true even though the entryPoints
list only contains a single entry, so the flag is a no-op. Update the build
options in the deno build script to remove splitting unless you intend to add
multiple entry points such as src/index.ts and default-entry.ts together in the
same entryPoints array. Keep the change localized to the build() call so the
configuration reflects the actual bundling behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/adapters/deno/src/default-entry.ts`:
- Line 76: The PORT parsing in default-entry should not use a truthy fallback
because Number(Deno.env.get("PORT")) || 3000 treats explicit 0 as missing.
Update the logic in default-entry to preserve a valid 0 value by checking for
NaN instead of using ||, so the existing port selection behavior remains
unchanged for unset or invalid values while allowing PORT=0 to pass through.

In `@packages/adapters/deno/src/index.ts`:
- Around line 1-13: The preview process in denoAdapter() is using shell
wrapping, which can leave the underlying deno child running after close().
Update the process launch in denoAdapter and its preview/close handling to avoid
shell: true by spawning deno directly, or if shell wrapping must stay, change
the termination logic to kill the full process group rather than only the
wrapper process. Use the denoAdapter symbol and the preview process setup to
locate the fix.

---

Nitpick comments:
In `@packages/adapters/deno/package.json`:
- Around line 23-26: The package currently has an empty test script, so wire up
a real test command in the scripts section and add at least minimal unit
coverage for the Deno adapter. Focus on the uniquely named entry points
`buildEnd` and `viteConfig`, covering the renaming behavior and
SSR/static-serving options described by `DenoPlatformInfo` so regressions are
caught even if line numbers shift.

In `@packages/adapters/deno/scripts/build.ts`:
- Around line 40-44: The build configuration in build() is setting splitting:
true even though the entryPoints list only contains a single entry, so the flag
is a no-op. Update the build options in the deno build script to remove
splitting unless you intend to add multiple entry points such as src/index.ts
and default-entry.ts together in the same entryPoints array. Keep the change
localized to the build() call so the configuration reflects the actual bundling
behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2483a3f2-8e91-4cc1-96f5-882dbb932f3e

📥 Commits

Reviewing files that changed from the base of the PR and between 779776f and 8f54062.

⛔ Files ignored due to path filters (2)
  • package-lock.json is excluded by !**/package-lock.json and included by **
  • packages/run/src/__tests__/fixtures/deno-adapter/__snapshots__/dev.expected.md is excluded by !**/__snapshots__/** and included by **
📒 Files selected for processing (18)
  • .changeset/deno-adapter.md
  • cspell.json
  • packages/adapters/deno/README.md
  • packages/adapters/deno/package.json
  • packages/adapters/deno/scripts/build.ts
  • packages/adapters/deno/scripts/importMetaURL.js
  • packages/adapters/deno/src/default-entry.ts
  • packages/adapters/deno/src/index.ts
  • packages/adapters/deno/src/types.ts
  • packages/adapters/deno/tsconfig.json
  • packages/run/src/__tests__/fixtures/deno-adapter/.gitignore
  • packages/run/src/__tests__/fixtures/deno-adapter/.marko-run/routes.d.ts
  • packages/run/src/__tests__/fixtures/deno-adapter/package.json
  • packages/run/src/__tests__/fixtures/deno-adapter/src/components/counter.marko
  • packages/run/src/__tests__/fixtures/deno-adapter/src/routes/+page.marko
  • packages/run/src/__tests__/fixtures/deno-adapter/test.config.ts
  • packages/run/src/__tests__/fixtures/deno-adapter/tsconfig.json
  • packages/run/src/__tests__/fixtures/deno-adapter/vite.config.ts

Comment thread packages/adapters/deno/src/default-entry.ts Outdated
Comment thread packages/adapters/deno/src/index.ts
rturnq added 4 commits July 1, 2026 03:36
The runtime's fetch returns a 404 response (not undefined) for unmatched
paths, so the entry must fall back to serving static assets on a 404
rather than only when fetch returns nothing. Otherwise requests for
static files (eg. /assets/*.js) returned 404 and the client bundle never
loaded.
- Add package.toggle.json so publish points exports/types at dist/
- Make the injected import.meta.url shim a string (.href) for the CJS build
- Fix the README platform example to read from context.platform
- Preserve an explicit PORT=0 (free port) instead of falling back to 3000
- Throw instead of exiting the process when the Deno CLI is missing
Use `shell: true` only on Windows. On POSIX the CLI is spawned directly,
so `close()` kills Deno itself instead of an orphaned shell wrapper and
argument values are no longer re-parsed by the shell. Also handle the
child's error event.
Clarify that Marko Run automatically uses an installed adapter with no
Vite config, and move the `npm run build` + deployctl deploy steps to a
Deploying section right after installation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant