Skip to content

feat(devvit): unify Vite build and Node oRPC server - #62

Merged
imjlk merged 6 commits into
mainfrom
codex/devvit-vite-plugin
Jul 13, 2026
Merged

imjlk merged 6 commits into
mainfrom
codex/devvit-vite-plugin

Conversation

@imjlk

@imjlk imjlk commented Jul 13, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • add an opt-in buildStrategy: "devvit-vite" target path that delegates client and server bundling to the official @devvit/start/vite plugin while preserving the legacy split-build path
  • upgrade generated Devvit targets to 0.13.7, share the game Vite configuration with the wrapper, and retain effective-config, icon, and release-provenance evidence
  • publish a direct @mpgd/bridge/orpc/node adapter backed by @orpc/server/node, remove Express/Helmet and Fetch conversion from generated targets, and preserve the explicit legacy /api/mpgd/bridge route
  • harden bounded request parsing, transport failures, security headers, production sourcemaps, Node ESM exports, templates, validators, docs, and Sampo release metadata

Compatibility

  • existing target configs remain on the legacy strategy unless they explicitly select devvit-vite
  • the legacy JSON bridge endpoint remains available for callers that explicitly configure it; new generated traffic uses oRPC
  • Devvit-owned menu, scheduler, trigger, and form callbacks remain thin Node HTTP routes; oRPC Publisher is documented as optional realtime fan-out rather than a scheduler replacement

Validation

  • pnpm check
  • pnpm test
  • pnpm build:packages
  • pnpm pack:packages:prepared
  • pnpm build:target reddit staging
  • pnpm build:target reddit production
  • pnpm smoke:target reddit
  • verified no production *.map artifacts
  • Open Code Review run per commit and over the complete branch; all actionable findings fixed, final full-branch review returned zero comments

Known upstream warning

The official Devvit Vite plugin currently emits a non-fatal sourcemapFileNames output-option warning with Vite 8.1.3. Both staging and production builds complete successfully; production sourcemaps are explicitly disabled and verified absent.

Summary by CodeRabbit

  • New Features

    • Added opt-in official Devvit Vite build strategy for generated Phaser games.
    • Exposed direct oRPC Node HTTP bridge adapter.
  • Dependency Updates

    • Upgraded Devvit packages to 0.13.7.
  • Changes

    • Simplified development workflow for Devvit targets.
    • Removed legacy bridge request conversion layer.
    • Updated build and playtest documentation.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@imjlk, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 24 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9564eb75-07bd-4557-8a5f-81fb724bebc6

📥 Commits

Reviewing files that changed from the base of the PR and between 74a201a and b4e3428.

📒 Files selected for processing (3)
  • apps/target-devvit/src/server/index.ts
  • packages/cli/templates/phaser-game/apps/target-devvit/src/server/index.ts
  • tools/validate-starter-workflow.ts
📝 Walkthrough

Walkthrough

This PR adds an opt-in official Devvit Vite build strategy, introduces a direct Node HTTP oRPC bridge adapter, migrates Devvit target servers from Express to native Node HTTP, and updates generated templates, validation, documentation, and Devvit package versions.

Changes

Devvit build and bridge integration

Layer / File(s) Summary
Node oRPC bridge adapter
packages/bridge/..., tsconfig.base.json
Adds the @mpgd/bridge/orpc/node export and Node HTTP handler with body limits, standardized errors, ESM imports, and smoke tests.
Native Devvit target server
apps/target-devvit/src/server/..., packages/cli/templates/phaser-game/apps/target-devvit/src/server/..., apps/target-devvit/src/client/*, packages/cli/templates/phaser-game/apps/target-devvit/src/client/*
Replaces Express request conversion with native Node routing, preserving legacy bridge and menu routes while adding direct oRPC handling and new Vite HTML entrypoints.
Shared Devvit Vite build strategy
examples/phaser-starter/vite.*, packages/cli/templates/phaser-game/vite.*, tools/target/*, apps/target-devvit/vite.config.ts
Adds shared Vite configuration, gateway and catalog resolution, runtime target metadata handling, devvit-vite target configuration, artifact branching, and layout validation.
Template workflow and release validation
.sampo/..., apps/target-devvit/README.md, packages/cli/templates/phaser-game/apps/target-devvit/README.md, tools/validate-starter-workflow.ts
Updates release metadata, Devvit 0.13.7 guidance, unified watch-build instructions, and starter-template checks for the official Devvit Vite setup.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant BuildTool
  participant ViteConfig
  participant DevvitPlugin
  participant TargetServer
  participant Bridge
  BuildTool->>ViteConfig: Select devvit-vite strategy
  ViteConfig->>DevvitPlugin: Build client and server bundles
  DevvitPlugin->>TargetServer: Emit unified Devvit artifacts
  TargetServer->>Bridge: Handle /api/mpgd/rpc
  Bridge-->>TargetServer: Return oRPC response
Loading

Possibly related PRs

  • imjlk/mpgd-kit#6: Adds overlapping Devvit bridge oRPC transport wiring and legacy bridge routing.
  • imjlk/mpgd-kit#7: Covers the matching Express-to-Node HTTP migration in the generated Devvit template.
  • imjlk/mpgd-kit#18: Addresses the prior Express-to-Fetch bridge conversion that this migration removes.

Suggested reviewers: github-actions[bot]

Poem

I’m a rabbit with Vite in my burrow tonight,
Node hops through bridges, clean and light.
Express fades softly, oRPC calls,
Unified builds rise past old walls.
The templates bloom, the tests cheer—
Devvit’s new path is hopping here!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 1.72% 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 is concise and accurately summarizes the main change: the unified Devvit Vite build plus Node oRPC server.
Description check ✅ Passed The description covers Summary and Validation clearly and is detailed enough, with only the Notes section left unfilled.
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 codex/devvit-vite-plugin

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@imjlk

imjlk commented Jul 13, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 13, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@imjlk

imjlk commented Jul 13, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 13, 2026 •

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@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: 1

🧹 Nitpick comments (1)
tools/validate-starter-workflow.ts (1)

862-978: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Validation function is comprehensive and well-structured.

The new validatePhaserTemplateDevvitVitePlugin() correctly checks:

  • Required files across both wrapper roots
  • Vite config markers (@devvit/start/vite, createGameViteSharedConfig, conditional sourcemaps)
  • Server entry for direct oRPC Node adapter and legacy bridge compatibility
  • Forbidden express/helmet imports
  • Package version consistency with expectedDevvitVersion
  • mpgd.targets.json build strategy set to devvit-vite

One note: the forbidden-package list at line 915 includes ['express', 'helmet'] but not hono. If Hono was also a removed dependency (as the READMEs suggest), consider adding it to the list. If the READMEs have a typo (should say "Helmet"), no change is needed here — this is tracked in the README review comments.

🤖 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 `@tools/validate-starter-workflow.ts` around lines 862 - 978, Extend the
forbiddenPackage list in validatePhaserTemplateDevvitVitePlugin to include hono
if it was removed from the Phaser template dependencies. Preserve the existing
import checks for express and helmet; make no change if Hono is intentionally
retained and the README reference is incorrect.
🤖 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 `@apps/target-devvit/src/server/index.ts`:
- Around line 760-771: Update the oversized-body handling around
assertContentLengthWithinLimit so requests with a declared Content-Length above
maxBodySize are not left unread: after returning 413, either drain/discard the
IncomingMessage stream while marking the response Connection: close, or close
the socket after flushing the response. Preserve normal processing for requests
within the limit.

---

Nitpick comments:
In `@tools/validate-starter-workflow.ts`:
- Around line 862-978: Extend the forbiddenPackage list in
validatePhaserTemplateDevvitVitePlugin to include hono if it was removed from
the Phaser template dependencies. Preserve the existing import checks for
express and helmet; make no change if Hono is intentionally retained and the
README reference is incorrect.
🪄 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: 39a28925-b9b8-4f85-90f1-a8d7e6d26207

📥 Commits

Reviewing files that changed from the base of the PR and between f81d3fa and 74a201a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (43)
  • .sampo/changesets/devvit-vite-node-orpc.md
  • adapters/devvit/package.json
  • apps/target-devvit/README.md
  • apps/target-devvit/devvit.json
  • apps/target-devvit/package.json
  • apps/target-devvit/src/client/game.html
  • apps/target-devvit/src/client/game.ts
  • apps/target-devvit/src/client/index.html
  • apps/target-devvit/src/client/preview.ts
  • apps/target-devvit/src/server/index.ts
  • apps/target-devvit/tsconfig.json
  • apps/target-devvit/vite.config.ts
  • apps/target-devvit/vite.server.config.ts
  • examples/phaser-starter/mpgd.targets.json
  • examples/phaser-starter/vite.config.ts
  • examples/phaser-starter/vite.shared.ts
  • packages/bridge/package.json
  • packages/bridge/src/cloudflare-pages.ts
  • packages/bridge/src/orpc-node.test.ts
  • packages/bridge/src/orpc-node.ts
  • packages/bridge/src/orpc.ts
  • packages/bridge/test/orpc-node-dist-import.mjs
  • packages/bridge/tsconfig.json
  • packages/cli/templates/phaser-game/apps/target-devvit/README.md
  • packages/cli/templates/phaser-game/apps/target-devvit/devvit.json
  • packages/cli/templates/phaser-game/apps/target-devvit/package.json
  • packages/cli/templates/phaser-game/apps/target-devvit/src/client/game.html
  • packages/cli/templates/phaser-game/apps/target-devvit/src/client/game.ts
  • packages/cli/templates/phaser-game/apps/target-devvit/src/client/index.html
  • packages/cli/templates/phaser-game/apps/target-devvit/src/client/preview.ts
  • packages/cli/templates/phaser-game/apps/target-devvit/src/server/index.ts
  • packages/cli/templates/phaser-game/apps/target-devvit/tsconfig.json
  • packages/cli/templates/phaser-game/apps/target-devvit/vite.config.ts
  • packages/cli/templates/phaser-game/apps/target-devvit/vite.server.config.ts
  • packages/cli/templates/phaser-game/mpgd.targets.json
  • packages/cli/templates/phaser-game/vite.config.ts
  • packages/cli/templates/phaser-game/vite.shared.ts
  • tools/target/build-target.ts
  • tools/target/platform-targets.ts
  • tools/target/schemas.ts
  • tools/target/validate-target-config.ts
  • tools/validate-starter-workflow.ts
  • tsconfig.base.json
💤 Files with no reviewable changes (2)
  • packages/cli/templates/phaser-game/apps/target-devvit/vite.server.config.ts
  • apps/target-devvit/vite.server.config.ts

Comment thread apps/target-devvit/src/server/index.ts Resolved

imjlk commented Jul 13, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

Please re-review the latest commit b4e3428, especially the oversized request connection handling. All local checks, full tests, Devvit staging build/smoke, and commit-scoped OpenCodeReview pass.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026 •

Copy link
Copy Markdown

@imjlk Understood — I'll re-review the latest commit (b4e3428), paying particular attention to the oversized request/connection handling in apps/target-devvit/src/server/index.ts (e.g., RequestBodyTooLargeError, readRequestBodyChunks, drainRequestBody, readJsonRequestBody, and content-length enforcement) along with the mirrored template in packages/cli/templates/phaser-game/apps/target-devvit/src/server/index.ts.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

imjlk commented Jul 13, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai The only actionable thread is now resolved and the suggested hono validator guard is included in b4e3428. Please confirm whether any actionable comments remain or whether no further re-review is needed before merge.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check open review threads/comments on the PR to confirm resolution status
gh pr view 62 --repo imjlk/mpgd-kit --json reviews,comments --jq '.reviews[] | {author: .author.login, state: .state, body: .body}' | head -100

echo "---THREADS---"
gh api graphql -f query='
query {
  repository(owner: "imjlk", name: "mpgd-kit") {
    pullRequest(number: 62) {
      reviewThreads(first: 50) {
        nodes {
          isResolved
          isOutdated
          comments(first: 5) {
            nodes {
              author { login }
              body
              path
              line
            }
          }
        }
      }
    }
  }
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | {isResolved: .isResolved, isOutdated: .isOutdated, path: .comments.nodes[0].path, body: .comments.nodes[0].body[0:200]}'

Length of output: 8436


🏁 Script executed:

#!/bin/bash
rg -n "hono" tools/validate-starter-workflow.ts -i
echo "---"
rg -n "forbiddenPackage" tools/validate-starter-workflow.ts -A5
echo "---content-length---"
rg -n "assertContentLengthWithinLimit|RequestBodyTooLargeError|Connection" apps/target-devvit/src/server/index.ts -B2 -A15

Length of output: 4332


Confirmed. Both items are resolved:

  1. Oversized declared-length request handling — assertContentLengthWithinLimit now throws before iterating, but discardOversizedRequestBody (Line 780) correctly drains the socket via request.resume() and sets connection: close before/around the 413 response, so the connection is no longer left hanging.
  2. hono forbidden-import check — tools/validate-starter-workflow.ts Line 915 now includes hono alongside express and helmet in the forbiddenPackage list.

I also re-checked all review threads via the GitHub API: the only actionable thread (oversized-body handling) is marked resolved, and no other open/unresolved actionable comments remain on the PR.

@imjlk No further actionable comments remain. From a review standpoint, this PR looks good to merge — nice work tightening up the bounded-body handling and the template validator guard.

(=^・ω・^=) ノ ready to merge

@imjlk
imjlk merged commit 2f06373 into main Jul 13, 2026
6 checks passed
@imjlk
imjlk deleted the codex/devvit-vite-plugin branch July 15, 2026 13:41
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