Skip to content

Conversation

@nicohrubec
Copy link
Member

@nicohrubec nicohrubec commented Jan 7, 2026

Adds sentryTanstackStart Vite plugin to enable automatic source map uploads in TanStack Start applications.

What it does
I tried to align with what we do in other SDKs (e.g. SvelteKit). On a high-level it:

  • Uploads source maps to Sentry using @sentry/vite-plugin if configured, passing through all options set by the user (including release, sourcemaps, headers, etc.)
  • If the source maps option is not defined and also the files to delete option is not defined, we enable cleaning up all .map files after the source map upload
  • If the source map configuration is undefined, we additionally enable hidden source map generation

Usage

// vite.config.ts
  import { defineConfig } from 'vite';
  import { sentryTanstackStart } from '@sentry/tanstackstart-react';
  import { tanstackStart } from '@tanstack/react-start/plugin/vite';

  export default defineConfig({
    plugins: [
      sentryTanstackStart({
        authToken: process.env.SENTRY_AUTH_TOKEN,
        org: 'my-org',
        project: 'my-project',
      }),
      tanstackStart(),
    ],
  });

Tests

  • Added unit tests for sourceMaps.ts and sentryTanstackStart.ts covering plugin composition, options passing, and source map settings logic
  • Updated the E2E test to use the new plugin pattern

Closes #18664

@github-actions
Copy link
Contributor

github-actions bot commented Jan 7, 2026

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.
⚠️ Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

Scenario Requests/s % of Baseline Prev. Requests/s Change %
GET Baseline 8,745 - 8,835 -1%
GET With Sentry 1,677 19% 1,750 -4%
GET With Sentry (error only) 6,027 69% 6,103 -1%
POST Baseline 1,180 - 1,198 -2%
POST With Sentry 578 49% 593 -3%
POST With Sentry (error only) 1,055 89% 1,049 +1%
MYSQL Baseline 3,335 - 3,292 +1%
MYSQL With Sentry 472 14% 450 +5%
MYSQL With Sentry (error only) 2,664 80% 2,687 -1%

View base workflow run

@nicohrubec nicohrubec changed the title feat(tanstackstart-react): Add vite config wrapper feat(tanstackstart-react): Add Vite Config Wrapper for Source Map Uploads Jan 8, 2026
@nicohrubec nicohrubec marked this pull request as ready for review January 8, 2026 08:37
/**
* Build options for the Sentry plugin. These options are used during build-time by the Sentry SDK.
*/
export type SentryTanstackStartReactPluginOptions = {
Copy link
Member

Choose a reason for hiding this comment

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

You can/should extend from this type, so we can make sure that all build-time options are aligned:

Copy link
Member Author

Choose a reason for hiding this comment

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

ah nice thanks I did not know that existed, updated

if (process.env.NODE_ENV !== 'development') {
// Check if source maps upload is enabled
// Default to enabled
const sourceMapsEnabled = options.sourceMapsUploadOptions?.enabled ?? true;
Copy link
Member

Choose a reason for hiding this comment

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

You probably want to use options.sourcemaps.disable here. Also make sure people can still create a release, even if they don't want to upload source maps.

Copy link
Member Author

Choose a reason for hiding this comment

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

updated to use disable

Copy link
Member Author

Choose a reason for hiding this comment

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

also always adding the sentry vite plugin down passing down the source maps disable option so that release creation works also if people do not use source maps

@s1gr1d
Copy link
Member

s1gr1d commented Jan 12, 2026

A general thought I had on this: Are the sources included in Nitro source maps? In the Nuxt SDK, we have to disable this setting:

nitroConfig.rollupConfig.output.sourcemapExcludeSources = false;

Copy link
Member

@Lms24 Lms24 left a comment

Choose a reason for hiding this comment

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

Naive question for now: What's the advantage over this wrapper that we can't achieve with just exporting a plugin? If we need to modify the vite config, Vite offers plugin hooks to do so from within a plugin.

I'd personally prefer the plugin approach because this is a pattern that users are more used to than wrapping their config. If you or anyone else has different opinions, let's hear it :D

@nicohrubec nicohrubec requested review from Lms24 and s1gr1d January 14, 2026 15:25
@nicohrubec nicohrubec changed the title feat(tanstackstart-react): Add Vite Config Wrapper for Source Map Uploads feat(tanstackstart-react): Add sentryTanstackStart Vite plugin for Source Map Uploads Jan 14, 2026
sourcemaps: { disable: true },
});

expect(plugins).toHaveLength(2);
Copy link
Member

Choose a reason for hiding this comment

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

super-l: we can use expect(plugins).toEqual([..., ..., ...]) here (+ in the tests below) instead of the length and find operations. I would argue the plugin order should be deterministic and we should fail the test if the order changes. Sometimes even plugins depend on each other, so the order matters.

Copy link
Member Author

Choose a reason for hiding this comment

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

updated


// Default to auto-deleting source maps from hidden directories after upload
// Users can override this by explicitly setting sourcemaps.filesToDeleteAfterUpload
const defaultFilesToDelete = ['.*/**/*.map'];
Copy link
Member

Choose a reason for hiding this comment

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

just to confirm: TSS' build output is in a hidden directory? (as opposed to something like /dist)?

Copy link
Member

Choose a reason for hiding this comment

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

When using nitro, it's .output but maybe it might be worth setting this to ./**/*.map as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

using ./**/*.map now to cover all cases

const plugins: Plugin[] = [];

// Only add plugins in production builds
if (process.env.NODE_ENV !== 'development') {
Copy link
Member

Choose a reason for hiding this comment

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

super-l: If we don't do anything in development, we could invert the if condition here and early return. Feel free to ignore, this is mostly just me preferring early returns and keeping the mainline logic outside of conditions 😅

Copy link
Member Author

Choose a reason for hiding this comment

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

jap fair enough I usually prefer this too, thanks for the comment I flipped it

const configPlugin: Plugin = {
name: 'sentry-tanstackstart-source-maps-config',
apply: 'build',
enforce: 'pre',
Copy link
Member

Choose a reason for hiding this comment

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

m: we probably want to enforce that configPlugin plugin runs 'post' so that we get the most likely final config object

actually now that I think about it, does this plugin do anything besides logging? Looks like we unconditionally set filesToDeleteAfterUpload when we create the @sentry/vite-plugin plugins (?)

Copy link
Member Author

Choose a reason for hiding this comment

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

  1. changed it to post
  2. true, had a subtle bug here. I moved the setting of filesToDeleteAfterUpload into the if/else so warning and setting actually align, so the plugin now determines the correct setting and also optionally warns now. also now use a promise as we do in SvelteKit for example that gets resolved in the plugin and is put into the sentry/vite-plugin since otherwise we cannot really ensure that we get the updated setting in the Vite-plugin

@nicohrubec nicohrubec requested a review from Lms24 January 16, 2026 14:49
export default defineConfig({
plugins: [
sentryTanstackStart({
org: 'your-org',
Copy link
Member

Choose a reason for hiding this comment

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

l: Nice changelog entry! Just for completeness I suggest we mention auth token here as well. Alternatively, we can just mention it in text (smthg like "Make sure to set the SENTRY_AUTH_TOKEN env var") since the env var is picked up automatically.

Suggested change
org: 'your-org',
authToken: process.env.SENTRY_AUTH_TOKEN,
org: 'your-org',

@nicohrubec nicohrubec changed the title feat(tanstackstart-react): Add sentryTanstackStart Vite plugin for Source Map Uploads feat(tanstackstart-react): Add sentryTanstackStart vite plugin to manage automatic source map uploads Jan 16, 2026
@nicohrubec nicohrubec merged commit 7401795 into develop Jan 16, 2026
164 checks passed
@nicohrubec nicohrubec deleted the nh/tss-vite-config-wrapper branch January 16, 2026 15:51
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.

Automatically enable source maps upload from vite config wrapper

4 participants