Skip to content

feat: create TanStack Start Bun server library#1

Merged
beeman merged 1 commit into
mainfrom
beeman/migrate-tanstack-start-bun-server
Apr 9, 2026
Merged

feat: create TanStack Start Bun server library#1
beeman merged 1 commit into
mainfrom
beeman/migrate-tanstack-start-bun-server

Conversation

@beeman
Copy link
Copy Markdown
Owner

@beeman beeman commented Apr 9, 2026

Create the initial tanstack-start-bun-server library.

This adds the Bun server package for running a TanStack Start app in production, along with docs, tests, and release metadata for the 1.0.0 launch.

Summary by CodeRabbit

  • New Features

    • Added Bun server utilities for serving TanStack Start production builds.
    • Introduced static asset handling with configurable gzip compression and ETag caching.
    • Customizable logging with console logger implementation.
    • Asset preloading with size thresholds and include/exclude pattern filtering.
    • Cache control headers optimized for versioned and non-versioned assets.
  • Documentation

    • Updated README with installation instructions and usage examples.
  • Tests

    • Added comprehensive test suite validating server and asset handling behavior.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 9, 2026

🦋 Changeset detected

Latest commit: 65d19d4

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

This PR includes changesets to release 1 package
Name Type
tanstack-start-bun-server Major

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
Copy link
Copy Markdown

coderabbitai Bot commented Apr 9, 2026

📝 Walkthrough

Walkthrough

A new Bun server library for serving TanStack Start production builds was introduced, replacing a simple greeting utility with comprehensive server configuration handling static asset preloading, caching, ETags, gzip compression, and dynamic server handler initialization.

Changes

Cohort / File(s) Summary
Release Documentation
.changeset/blue-snails-judge.md
New Changeset entry marking major version bump for initial tanstack-start-bun-server release with static asset handling, caching, and comprehensive test coverage.
Package Configuration
package.json
Updated description, added TypeScript to devDependencies, introduced Bun export entry, expanded published files to include src, removed peerDependencies, and added sideEffects: false.
Documentation
README.md
Comprehensive rewrite documenting Bun-only serving utilities; added installation, multiple usage examples for createTanStackStartBunServeConfig, logger configuration, gzip MIME type customization, and asset route integration.
Server Core Exports
src/index.ts
Replaced greet() function with new exports: DEFAULT_GZIP_MIME_TYPES, Logger type, createConsoleLogger, and introduced async createTanStackStartBunServeConfig() factory with TanStackStartBunServeConfig and TanStackStartBunServeOptions interfaces.
Logging Infrastructure
src/logger.ts
Added new Logger interface with debug, error, and info methods and implemented createConsoleLogger() factory for console-based logging with prefixed output.
Server Handler
src/server-handler.ts
Added ServerHandler interface and initializeServerHandler() function to dynamically load and initialize server entry point from webDistPath/server/server.js with fallback 404 response.
Static Asset Management
src/static-assets.ts
New module implementing initializeStaticRoutes() with sophisticated asset preloading, gzip compression, ETag generation, glob-based filtering, cache-control headers, and 304 Not Modified revalidation support.
Tests
test/index.test.ts, test/logger.test.ts, test/tanstack-start-bun-server.test.ts
Removed old greeting test; added logger tests verifying console output with prefixes; added comprehensive server config tests validating preloading, caching, gzip negotiation, ETag revalidation, pattern filtering, and versioned asset handling.

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant TanStackStartBunServeConfig
    participant StaticAssets
    participant ServerHandler
    participant Bun as Bun.file / Memory
    
    Client->>TanStackStartBunServeConfig: createTanStackStartBunServeConfig(options)
    activate TanStackStartBunServeConfig
    
    TanStackStartBunServeConfig->>StaticAssets: initializeStaticRoutes(options)
    activate StaticAssets
    StaticAssets->>Bun: glob scan webDistPath/client
    StaticAssets->>Bun: filter by include/exclude patterns
    StaticAssets->>Bun: preload eligible assets (within maxPreloadBytes)
    StaticAssets->>Bun: compute gzip & ETag if enabled
    StaticAssets-->>TanStackStartBunServeConfig: { loaded, routes, skipped }
    deactivate StaticAssets
    
    TanStackStartBunServeConfig->>ServerHandler: initializeServerHandler(options)
    activate ServerHandler
    ServerHandler->>Bun: check webDistPath/server/server.js exists
    ServerHandler->>Bun: dynamic import server module
    ServerHandler-->>TanStackStartBunServeConfig: ServerHandler instance
    deactivate ServerHandler
    
    TanStackStartBunServeConfig-->>Client: { fetchHandler, routes }
    deactivate TanStackStartBunServeConfig
    
    Client->>Client: route GET /asset.css to routes['/asset.css']
    activate Client
    Client->>StaticAssets: routes['/asset.css'](request)
    activate StaticAssets
    alt preloaded & ETag matches
        StaticAssets-->>Client: 304 Not Modified
    else preloaded & accept-encoding: gzip
        StaticAssets-->>Client: 200 with gzipped body + Content-Encoding: gzip
    else preloaded
        StaticAssets-->>Client: 200 with body
    else not preloaded
        StaticAssets->>Bun: Bun.file(path)
        Bun-->>StaticAssets: streamed response
        StaticAssets-->>Client: 200 streamed
    end
    deactivate StaticAssets
    deactivate Client
    
    Client->>Client: route POST /api/* to fetchHandler
    activate Client
    Client->>ServerHandler: fetchHandler(request)
    activate ServerHandler
    ServerHandler->>Bun: serverModule.default.fetch(request)
    Bun-->>ServerHandler: application response
    ServerHandler-->>Client: 200 application response
    deactivate ServerHandler
    deactivate Client
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 Beep boop, our Bun server hops along,
Static assets preloaded, gzipped strong,
ETags revalidate, caches sing,
TanStack Start on Bun—what joy to bring! 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: create TanStack Start Bun server library' directly and clearly summarizes the main change—introducing a new library for serving TanStack Start applications on Bun, which is the primary focus of all file changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch beeman/migrate-tanstack-start-bun-server

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
src/static-assets.ts (2)

275-296: Consider caching on-demand loaded assets.

Assets that pass size limits but fail pattern matching are reloaded from disk on every request (line 276-290). Under high traffic for frequently accessed filtered assets, this incurs repeated disk I/O and gzip compression overhead.

A simple LRU cache could reduce this cost, but for v1.0 with typical usage patterns, this is acceptable to defer.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/static-assets.ts` around lines 275 - 296, Assets that pass
withinSizeLimit but are rebuilt on every request (the routes[route] branch that
calls loadAssetFromFile then createAssetResponse) should be cached to avoid
repeated disk/GZIP work; implement a small LRU (or bounded) cache keyed by
filepath + relevant options (enableEtag, enableGzip, gzipMimeTypes,
gzipMinBytes, relativePath, metadata.type) and return the cached asset when
present, falling back to calling loadAssetFromFile and storing the result on
miss; keep createStreamingAssetResponse branch unchanged. Ensure cache
eviction/bounded size to avoid unbounded memory growth and use the same cached
asset object expected by createAssetResponse.

79-82: Static analysis flagged potential ReDoS - low risk in practice.

The convertGlobToRegExp function builds a regex from user-provided glob patterns. While the escaping handles most special characters, pathological patterns could theoretically cause backtracking. In practice, patterns are simple file globs like *.js or *.css, making exploitation unlikely.

If this library may receive untrusted pattern input, consider adding a pattern complexity check or timeout. For typical usage with developer-controlled configuration, this is acceptable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/static-assets.ts` around lines 79 - 82, The convertGlobToRegExp function
can produce regexes that, if crafted by untrusted input, may trigger ReDoS;
update convertGlobToRegExp to validate and constrain pattern complexity before
building the RegExp: enforce a reasonable max length (e.g., 200–1000 chars) and
reject or truncate patterns with excessive consecutive wildcards (e.g., >5 '*'),
and replace '*' with a safer subpattern like '[^/]*' (or otherwise restrict
wildcard scope) instead of '.*' to reduce backtracking risk; keep the existing
escaping logic and throw or return a safe fallback when checks fail.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/static-assets.ts`:
- Around line 275-296: Assets that pass withinSizeLimit but are rebuilt on every
request (the routes[route] branch that calls loadAssetFromFile then
createAssetResponse) should be cached to avoid repeated disk/GZIP work;
implement a small LRU (or bounded) cache keyed by filepath + relevant options
(enableEtag, enableGzip, gzipMimeTypes, gzipMinBytes, relativePath,
metadata.type) and return the cached asset when present, falling back to calling
loadAssetFromFile and storing the result on miss; keep
createStreamingAssetResponse branch unchanged. Ensure cache eviction/bounded
size to avoid unbounded memory growth and use the same cached asset object
expected by createAssetResponse.
- Around line 79-82: The convertGlobToRegExp function can produce regexes that,
if crafted by untrusted input, may trigger ReDoS; update convertGlobToRegExp to
validate and constrain pattern complexity before building the RegExp: enforce a
reasonable max length (e.g., 200–1000 chars) and reject or truncate patterns
with excessive consecutive wildcards (e.g., >5 '*'), and replace '*' with a
safer subpattern like '[^/]*' (or otherwise restrict wildcard scope) instead of
'.*' to reduce backtracking risk; keep the existing escaping logic and throw or
return a safe fallback when checks fail.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0bc866f4-5255-4ad9-9f12-c326d646bdb4

📥 Commits

Reviewing files that changed from the base of the PR and between 78525ae and c02363f.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (10)
  • .changeset/blue-snails-judge.md
  • README.md
  • package.json
  • src/index.ts
  • src/logger.ts
  • src/server-handler.ts
  • src/static-assets.ts
  • test/index.test.ts
  • test/logger.test.ts
  • test/tanstack-start-bun-server.test.ts
💤 Files with no reviewable changes (1)
  • test/index.test.ts

Create the initial tanstack-start-bun-server library.

This adds the Bun server package for running a TanStack Start app in production, along with docs, tests, and release metadata for the 1.0.0 launch.
@beeman beeman force-pushed the beeman/migrate-tanstack-start-bun-server branch from c02363f to 65d19d4 Compare April 9, 2026 22:20
@beeman beeman merged commit 65d19d4 into main Apr 9, 2026
4 checks passed
@beeman beeman deleted the beeman/migrate-tanstack-start-bun-server branch April 10, 2026 05:06
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