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 ./distHow 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-pluginConfiguration
// 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
| Option | Type | Default | Description |
|---|---|---|---|
| authToken | string | TRACEKIT_AUTH_TOKEN env | API auth token. Falls back to the TRACEKIT_AUTH_TOKEN environment variable. |
| url | string | "https://app.tracekit.dev" | TraceKit server URL. |
| release | string | auto-detect | Release version. Auto-detected from package.json version if not specified. |
| strict | boolean | false | Fail the build if source map upload encounters an error. |
| disabled | boolean | false | Disable the plugin entirely. Useful for toggling via environment variable. |
| silent | boolean | false | Suppress all console output from the plugin. |
Webpack Plugin @tracekit/webpack-plugin
Install
npm install -D @tracekit/webpack-pluginConfiguration
// 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
| Option | Type | Default | Description |
|---|---|---|---|
| authToken | string | TRACEKIT_AUTH_TOKEN env | API auth token. Falls back to the TRACEKIT_AUTH_TOKEN environment variable. |
| url | string | "https://app.tracekit.dev" | TraceKit server URL. |
| release | string | auto-detect | Release version. Auto-detected from package.json version if not specified. |
| strict | boolean | false | Add upload errors to webpack compilation errors (fails the build). |
| disabled | boolean | false | Disable the plugin entirely. |
| silent | boolean | false | Suppress 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
| Flag | Type | Description |
|---|---|---|
| --release | string | Release version to tag the upload. Auto-detected from package.json or git tag if not provided. |
| --json | boolean | Output 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 --jsonsourcemaps delete
Delete all source maps associated with a specific release. Useful for rotating old releases or re-uploading corrected maps.
Flags
| Flag | Type | Description |
|---|---|---|
| --release | string | Required. Release version whose source maps should be deleted. |
| --json | boolean | Output 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 --jsonHow 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.
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.
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.
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.
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.
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.
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.
Upload a source map file. Uses multipart/form-data encoding.
Form fields
| Field | Type | Required | Description |
|---|---|---|---|
| sourcemap | file | Yes | The .js.map file. |
| debug_id | string | Yes | The debug ID (UUID) injected into the corresponding .js file. |
| release | string | No | Release 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 all source maps for a specific release.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| release | string | Required. 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-446655440000If 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_TOKENenvironment variable is set correctly, or passauthTokenin 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, setdevtool: 'source-map'.
# Test upload manually to see detailed errors
tracekit sourcemaps upload ./dist --release v1.2.3
# Verify auth
tracekit statusSymbolication 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.3Tip: 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 productionOption 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.