Source Maps

Upload source maps to resolve minified JavaScript stack traces back to your original source code. Use build plugins for automatic upload or the CLI for manual control.

Quick Start

The fastest way to get source maps working is with a build plugin. Three lines in your Vite config:

// vite.config.ts
import { tracekitVitePlugin } from '@tracekit/vite-plugin';

export default defineConfig({
  build: { sourcemap: true },
  plugins: [tracekitVitePlugin()],
});

Or upload manually with the CLI:

tracekit sourcemaps upload ./dist

How it works: Both the build plugins and CLI automatically inject debug IDs (per ECMA-426) into your built JavaScript files and their corresponding source maps. The browser SDK reads these IDs at runtime, and the server matches them to uploaded maps for symbolication. No manual configuration needed.

Build Plugins

Build plugins handle everything automatically: they inject debug IDs into your output files and upload source maps to TraceKit after the build completes. Both plugins share the same configuration interface and only run when CI=true (they skip local development builds).

Vite Plugin @tracekit/vite-plugin

Install

npm install -D @tracekit/vite-plugin

Configuration

// vite.config.ts
import { defineConfig } from 'vite';
import { tracekitVitePlugin } from '@tracekit/vite-plugin';

export default defineConfig({
  build: { sourcemap: true },  // Required: enable source maps
  plugins: [
    tracekitVitePlugin({
      // Auth token — reads TRACEKIT_AUTH_TOKEN env var by default
      authToken: process.env.TRACEKIT_AUTH_TOKEN,
      // Server URL — default: https://app.tracekit.dev
      url: 'https://app.tracekit.dev',
      // Release version — auto-detected from package.json if omitted
      release: '1.0.0',
      // Fail the build on upload error — default: false
      strict: false,
      // Disable the plugin entirely — default: false
      disabled: false,
      // Suppress console output — default: false
      silent: false,
    }),
  ],
});

Important: You must set build.sourcemap: true in your Vite config. Without it, Vite will not generate .js.map files and the plugin will have nothing to upload.

Options

OptionTypeDefaultDescription
authTokenstringTRACEKIT_AUTH_TOKEN envAPI auth token. Falls back to the TRACEKIT_AUTH_TOKEN environment variable.
urlstring"https://app.tracekit.dev"TraceKit server URL.
releasestringauto-detectRelease version. Auto-detected from package.json version if not specified.
strictbooleanfalseFail the build if source map upload encounters an error.
disabledbooleanfalseDisable the plugin entirely. Useful for toggling via environment variable.
silentbooleanfalseSuppress all console output from the plugin.

Webpack Plugin @tracekit/webpack-plugin

Install

npm install -D @tracekit/webpack-plugin

Configuration

// webpack.config.js
const { TracekitWebpackPlugin } = require('@tracekit/webpack-plugin');

module.exports = {
  devtool: 'source-map',  // Required: enable source maps
  plugins: [
    new TracekitWebpackPlugin({
      // Auth token — reads TRACEKIT_AUTH_TOKEN env var by default
      authToken: process.env.TRACEKIT_AUTH_TOKEN,
      // Server URL — default: https://app.tracekit.dev
      url: 'https://app.tracekit.dev',
      // Release version — auto-detected from package.json if omitted
      release: '1.0.0',
      // Fail the build on upload error — default: false
      strict: false,
      // Disable the plugin entirely — default: false
      disabled: false,
      // Suppress console output — default: false
      silent: false,
    }),
  ],
};

Important: You must set devtool: 'source-map' in your webpack config. Other devtool values (like eval-source-map or cheap-module-source-map) may not produce standard .js.map files.

Options

OptionTypeDefaultDescription
authTokenstringTRACEKIT_AUTH_TOKEN envAPI auth token. Falls back to the TRACEKIT_AUTH_TOKEN environment variable.
urlstring"https://app.tracekit.dev"TraceKit server URL.
releasestringauto-detectRelease version. Auto-detected from package.json version if not specified.
strictbooleanfalseAdd upload errors to webpack compilation errors (fails the build).
disabledbooleanfalseDisable the plugin entirely.
silentbooleanfalseSuppress all console output from the plugin.

CLI Upload

Use the TraceKit CLI for manual source map management. The CLI handles debug ID injection and upload in a single command.

sourcemaps upload [path]

Recursively discovers .js.map files in the given directory, injects debug IDs (ECMA-426 format: //# debugId=<uuid>) into both the .js and .js.map files, and uploads the source maps to the TraceKit server.

Debug ID injection is idempotent: existing debug IDs in .js files are preserved on re-run. If no path is provided, the current directory is scanned. node_modules directories are automatically skipped.

Flags

FlagTypeDescription
--releasestringRelease version to tag the upload. Auto-detected from package.json or git tag if not provided.
--jsonbooleanOutput upload results as JSON for CI/CD integration.

Examples

# Upload source maps from dist directory
tracekit sourcemaps upload ./dist

# Upload with explicit release version
tracekit sourcemaps upload ./dist --release v1.2.3

# Upload from current directory
tracekit sourcemaps upload

# JSON output for CI pipelines
tracekit sourcemaps upload ./dist --release v1.2.3 --json

sourcemaps delete

Delete all source maps associated with a specific release. Useful for rotating old releases or re-uploading corrected maps.

Flags

FlagTypeDescription
--releasestringRequired. Release version whose source maps should be deleted.
--jsonbooleanOutput results as JSON.

Examples

# Delete source maps for a release
tracekit sourcemaps delete --release v1.2.3

# Delete with JSON output
tracekit sourcemaps delete --release v1.2.3 --json

How Symbolication Works

Symbolication is the process of resolving minified stack frames back to original source locations. TraceKit uses debug IDs to match production errors to uploaded source maps.

1

Debug ID injection

During build (via plugin) or upload (via CLI), a unique UUID is injected as a //# debugId=<uuid> comment into each .js file and as a "debugId" field in the corresponding .js.map file. This follows the TC39 ECMA-426 standard.

2

Source maps uploaded and stored server-side

Source maps are uploaded to the TraceKit server and stored on the filesystem with metadata in PostgreSQL. They are never served publicly via HTTP -- your source code remains private. Uploaded maps are retained for 90 days, after which a cleanup worker removes them.

3

Browser SDK captures errors with debug IDs

When the browser SDK captures an error, it reads the debug IDs from the loaded scripts on the page. These IDs are sent along with the error event to the server.

4

Server matches debug IDs to uploaded maps

The server looks up the uploaded source map by its debug ID. This is more reliable than filename-based matching because debug IDs survive CDN transformations and cache-busted filenames.

5

Asynchronous symbolication

Stack frames are resolved asynchronously in a background goroutine. Each minified frame (file, line, column) is mapped to the original file path, line number, column, and function name. This happens with zero impact on ingestion latency.

6

Resolved stack trace in UI

The error detail page displays the resolved stack trace with original source file paths, line numbers, column numbers, and function names. You see your code as written, not the minified version.

Security and retention

  • Source maps are never served via HTTP GET. Your source code is not publicly accessible.
  • 90-day retention. Source maps older than 90 days are removed by a daily cleanup worker.
  • Re-upload safe. Uploading the same debug ID overwrites the previous map (via ON CONFLICT DO UPDATE).

REST API

All endpoints require an X-API-Key header with your organization API key.

Important: Source map endpoints require a private (secret) API key. Public (client-side) keys are rejected. You can find your private key in Settings → API Keys. Never expose your private key in client-side code -- use it only in CI pipelines, build scripts, or server-side tooling.

POST /api/sourcemaps

Upload a source map file. Uses multipart/form-data encoding.

Form fields

FieldTypeRequiredDescription
sourcemapfileYesThe .js.map file.
debug_idstringYesThe debug ID (UUID) injected into the corresponding .js file.
releasestringNoRelease version to associate with this source map.

Example (curl)

curl -X POST https://app.tracekit.dev/api/sourcemaps \
  -H "X-API-Key: your-private-api-key" \
  -F "debug_id=550e8400-e29b-41d4-a716-446655440000" \
  -F "release=v1.2.3" \
  -F "sourcemap=@./dist/main.abc123.js.map"
DELETE /api/sourcemaps

Delete all source maps for a specific release.

Query parameters

ParameterTypeDescription
releasestringRequired. Release version whose source maps should be deleted.

Response 200 OK

{
  "deleted_count": 5,
  "release": "v1.2.3"
}

Troubleshooting

Debug IDs not appearing in built files

If your production error stack traces are not being resolved, check that debug IDs are present in your built .js files.

# Check for debug IDs in built files
grep -r "debugId=" ./dist/*.js

# You should see lines like:
# //# debugId=550e8400-e29b-41d4-a716-446655440000

If no debug IDs are found: (1) verify your build plugin is installed and configured, (2) check that CI=true is set in your CI environment (plugins skip local builds), (3) if using the CLI, run tracekit sourcemaps upload which injects IDs during upload.

Source map upload failures

Common causes of upload failures:

  • - Authentication error: Verify your TRACEKIT_AUTH_TOKEN environment variable is set correctly, or pass authToken in the plugin config.
  • - Network timeout: The CLI uses a 60-second timeout for large source maps. If your maps are very large, check your network connection.
  • - No .js.map files found: Verify that source maps are being generated. For Vite, set build.sourcemap: true. For Webpack, set devtool: 'source-map'.
# Test upload manually to see detailed errors
tracekit sourcemaps upload ./dist --release v1.2.3

# Verify auth
tracekit status

Symbolication not working

If errors appear with minified stack traces despite uploading source maps:

  • - Debug ID mismatch: The debug IDs in your production bundles must match the ones in the uploaded source maps. Re-building and re-uploading without using the same build output will generate different IDs.
  • - Wrong release: If you tagged source maps with a specific release, verify the production build is using the same release version in its SDK config.
  • - Expired maps: Source maps are retained for 90 days. If your release is older, re-upload the source maps.

Source maps tagged with wrong release

If source maps were uploaded with the wrong release tag, delete them and re-upload with the correct release:

# Delete maps for the wrong release
tracekit sourcemaps delete --release wrong-version

# Re-upload with the correct release
tracekit sourcemaps upload ./dist --release v1.2.3

Tip: Use the --release flag explicitly in CI/CD pipelines to avoid auto-detection picking up the wrong version.

Verifying uploaded source maps

To verify that source maps were uploaded successfully, use the --json flag during upload to see detailed results:

tracekit sourcemaps upload ./dist --release v1.2.3 --json

# Output:
# [
#   {
#     "debug_id": "550e8400-e29b-41d4-a716-446655440000",
#     "filename": "main.abc123.js.map",
#     "size_bytes": 245760,
#     "release": "v1.2.3"
#   }
# ]

Complete Example

A full CI/CD pipeline that builds, uploads source maps, and creates a release in a single workflow.

Option A: Build plugin (Vite)

With the Vite plugin configured, source maps are uploaded automatically during the build step. Combine with the CLI for release tracking.

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { tracekitVitePlugin } from '@tracekit/vite-plugin';

export default defineConfig({
  build: { sourcemap: true },
  plugins: [
    react(),
    tracekitVitePlugin({
      release: process.env.RELEASE_VERSION,
      strict: true,  // Fail CI if upload fails
    }),
  ],
});
# CI/CD pipeline (GitHub Actions, etc.)
export CI=true
export TRACEKIT_AUTH_TOKEN=${{ secrets.TRACEKIT_AUTH_TOKEN }}
export RELEASE_VERSION=$(git describe --tags --always)

# Build — source maps are uploaded automatically by the Vite plugin
npm run build

# Create and deploy the release
tracekit releases deploy --env production

Option B: CLI upload (any build tool)

If you are not using Vite or Webpack, build normally and use the CLI to upload source maps and create the release.

# CI/CD pipeline
VERSION=$(git describe --tags --always)

# 1. Build your app (ensure source maps are generated)
npm run build

# 2. Upload source maps with debug ID injection
tracekit sourcemaps upload ./dist --release $VERSION

# 3. Create release and register deploy
tracekit releases deploy $VERSION --env production

# 4. (Optional) Deploy your app
rsync -avz ./dist/ server:/app/public/

See also: Release Tracking for the full CLI commands reference, REST API endpoints, and dashboard usage.