diff --git a/package.json b/package.json
index 21457ec324a3..44ac0d95b9a3 100644
--- a/package.json
+++ b/package.json
@@ -87,6 +87,7 @@
"packages/replay-internal",
"packages/replay-canvas",
"packages/replay-worker",
+ "packages/server-utils",
"packages/solid",
"packages/solidstart",
"packages/svelte",
diff --git a/packages/core/package.json b/packages/core/package.json
index 23f783667d7d..5285e3857a65 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -92,7 +92,40 @@
"extends": "../../package.json"
},
"sideEffects": false,
+ "dependencies": {
+ "@sentry-internal/server-utils": "10.54.0"
+ },
"devDependencies": {
"zod": "^3.24.1"
+ },
+ "nx": {
+ "targets": {
+ "build:transpile": {
+ "dependsOn": []
+ },
+ "build:types": {
+ "dependsOn": []
+ },
+ "build:dev": {
+ "dependsOn": []
+ },
+ "build:tarball": {
+ "dependsOn": [
+ "build:transpile",
+ "build:types"
+ ]
+ },
+ "test:unit": {
+ "dependsOn": [
+ "build:transpile",
+ "build:types"
+ ]
+ },
+ "lint": {
+ "dependsOn": [
+ "build:types"
+ ]
+ }
+ }
}
}
diff --git a/packages/server-utils/.oxlintrc.json b/packages/server-utils/.oxlintrc.json
new file mode 100644
index 000000000000..4cd4930fa802
--- /dev/null
+++ b/packages/server-utils/.oxlintrc.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "../../node_modules/oxlint/configuration_schema.json",
+ "extends": ["../../.oxlintrc.base.json"]
+}
diff --git a/packages/server-utils/LICENSE b/packages/server-utils/LICENSE
new file mode 100644
index 000000000000..b956a1944c7b
--- /dev/null
+++ b/packages/server-utils/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Functional Software, Inc. dba Sentry
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/packages/server-utils/README.md b/packages/server-utils/README.md
new file mode 100644
index 000000000000..fdcbbfef9139
--- /dev/null
+++ b/packages/server-utils/README.md
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+# Sentry JavaScript SDK Server Utilities
+
+[](https://www.npmjs.com/package/@sentry-internal/server-utils)
+[](https://www.npmjs.com/package/@sentry-internal/server-utils)
+[](https://www.npmjs.com/package/@sentry-internal/server-utils)
+
+## Links
+
+- [Official SDK Docs](https://docs.sentry.io/quickstart/)
+
+## General
+
+Common server-side utilities used by the Sentry JavaScript Server SDKs (Node, Bun, Deno, Cloudflare, AWS Lambda, Google
+Cloud Functions, Vercel Edge).
+
+Note: This package is only meant to be used internally, and as such is not part of our public API contract and does not
+follow semver.
diff --git a/packages/server-utils/package.json b/packages/server-utils/package.json
new file mode 100644
index 000000000000..02a9cbeb92c7
--- /dev/null
+++ b/packages/server-utils/package.json
@@ -0,0 +1,69 @@
+{
+ "name": "@sentry-internal/server-utils",
+ "version": "10.54.0",
+ "description": "Server Utilities for all Sentry JavaScript Server SDKs",
+ "repository": "git://github.com/getsentry/sentry-javascript.git",
+ "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/server-utils",
+ "author": "Sentry",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "files": [
+ "/build"
+ ],
+ "main": "build/cjs/index.js",
+ "module": "build/esm/index.js",
+ "types": "build/types/index.d.ts",
+ "exports": {
+ "./package.json": "./package.json",
+ ".": {
+ "import": {
+ "types": "./build/types/index.d.ts",
+ "default": "./build/esm/index.js"
+ },
+ "require": {
+ "types": "./build/types/index.d.ts",
+ "default": "./build/cjs/index.js"
+ }
+ }
+ },
+ "typesVersions": {
+ "<5.0": {
+ "build/types/index.d.ts": [
+ "build/types-ts3.8/index.d.ts"
+ ]
+ }
+ },
+ "publishConfig": {
+ "access": "public"
+ },
+ "dependencies": {
+ "@sentry/core": "10.54.0"
+ },
+ "scripts": {
+ "build": "run-p build:transpile build:types",
+ "build:dev": "yarn build",
+ "build:transpile": "rollup -c rollup.npm.config.mjs",
+ "build:types": "run-s build:types:core build:types:downlevel",
+ "build:types:core": "tsc -p tsconfig.types.json",
+ "build:types:downlevel": "yarn downlevel-dts build/types build/types-ts3.8 --to ts3.8",
+ "build:watch": "run-p build:transpile:watch",
+ "build:dev:watch": "run-p build:transpile:watch",
+ "build:transpile:watch": "rollup -c rollup.npm.config.mjs --watch",
+ "build:tarball": "npm pack",
+ "circularDepCheck": "madge --circular src/index.ts",
+ "clean": "rimraf build coverage sentry-internal-server-utils-*.tgz",
+ "lint:fix": "OXLINT_TSGOLINT_DANGEROUSLY_SUPPRESS_PROGRAM_DIAGNOSTICS=true oxlint . --fix --type-aware",
+ "lint": "OXLINT_TSGOLINT_DANGEROUSLY_SUPPRESS_PROGRAM_DIAGNOSTICS=true oxlint . --type-aware",
+ "lint:es-compatibility": "es-check es2020 ./build/cjs/*.js && es-check es2020 ./build/esm/*.js --module",
+ "test:unit": "vitest run",
+ "test": "vitest run",
+ "test:watch": "vitest --watch",
+ "yalc:publish": "yalc publish --push --sig"
+ },
+ "volta": {
+ "extends": "../../package.json"
+ },
+ "sideEffects": false
+}
diff --git a/packages/server-utils/rollup.npm.config.mjs b/packages/server-utils/rollup.npm.config.mjs
new file mode 100644
index 000000000000..d28a7a6f54a0
--- /dev/null
+++ b/packages/server-utils/rollup.npm.config.mjs
@@ -0,0 +1,17 @@
+import { makeBaseNPMConfig, makeNPMConfigVariants } from '@sentry-internal/rollup-utils';
+
+export default makeNPMConfigVariants(
+ makeBaseNPMConfig({
+ packageSpecificConfig: {
+ output: {
+ // set exports to 'named' or 'auto' so that rollup doesn't warn
+ exports: 'named',
+ // set preserveModules to true because we don't want to bundle everything into one file.
+ preserveModules:
+ process.env.SENTRY_BUILD_PRESERVE_MODULES === undefined
+ ? true
+ : Boolean(process.env.SENTRY_BUILD_PRESERVE_MODULES),
+ },
+ },
+ }),
+);
diff --git a/packages/server-utils/src/index.ts b/packages/server-utils/src/index.ts
new file mode 100644
index 000000000000..6dfa1d221b70
--- /dev/null
+++ b/packages/server-utils/src/index.ts
@@ -0,0 +1,4 @@
+// Public surface intentionally left empty in this initial scaffold.
+// Symbols will land here as code is migrated out of `@sentry/core` per the
+// server-utils migration plan.
+export {};
diff --git a/packages/server-utils/test/index.test.ts b/packages/server-utils/test/index.test.ts
new file mode 100644
index 000000000000..b3240613713d
--- /dev/null
+++ b/packages/server-utils/test/index.test.ts
@@ -0,0 +1,9 @@
+import { describe, expect, it } from 'vitest';
+
+import * as ServerUtils from '../src/index';
+
+describe('@sentry-internal/server-utils', () => {
+ it('loads the package entry point', () => {
+ expect(ServerUtils).toBeDefined();
+ });
+});
diff --git a/packages/server-utils/test/tsconfig.json b/packages/server-utils/test/tsconfig.json
new file mode 100644
index 000000000000..38ca0b13bcdd
--- /dev/null
+++ b/packages/server-utils/test/tsconfig.json
@@ -0,0 +1,3 @@
+{
+ "extends": "../tsconfig.test.json"
+}
diff --git a/packages/server-utils/tsconfig.json b/packages/server-utils/tsconfig.json
new file mode 100644
index 000000000000..bf45a09f2d71
--- /dev/null
+++ b/packages/server-utils/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.json",
+
+ "include": ["src/**/*"],
+
+ "compilerOptions": {
+ // package-specific options
+ }
+}
diff --git a/packages/server-utils/tsconfig.test.json b/packages/server-utils/tsconfig.test.json
new file mode 100644
index 000000000000..b2ccc6d8b08c
--- /dev/null
+++ b/packages/server-utils/tsconfig.test.json
@@ -0,0 +1,12 @@
+{
+ "extends": "./tsconfig.json",
+
+ "include": ["test/**/*", "vite.config.ts"],
+
+ "compilerOptions": {
+ // should include all types from `./tsconfig.json` plus types for all test frameworks used
+ "types": ["node", "vitest"]
+
+ // other package-specific, test-specific options
+ }
+}
diff --git a/packages/server-utils/tsconfig.types.json b/packages/server-utils/tsconfig.types.json
new file mode 100644
index 000000000000..b1a51db073c2
--- /dev/null
+++ b/packages/server-utils/tsconfig.types.json
@@ -0,0 +1,9 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "declaration": true,
+ "declarationMap": true,
+ "emitDeclarationOnly": true,
+ "outDir": "build/types"
+ }
+}
diff --git a/packages/server-utils/vite.config.ts b/packages/server-utils/vite.config.ts
new file mode 100644
index 000000000000..f18ec92095bc
--- /dev/null
+++ b/packages/server-utils/vite.config.ts
@@ -0,0 +1,8 @@
+import baseConfig from '../../vite/vite.config';
+
+export default {
+ ...baseConfig,
+ test: {
+ ...baseConfig.test,
+ },
+};