Learn
Project Structure

Project Structure

A Traceway project is an observability boundary. It controls which telemetry shares dashboards and distributed traces, which framework-specific setup appears on the Connection page, and which runtime and artifact-upload credentials are used.

Choose projects around application runtime boundaries, not folders or processes.

Recommended Structure

Application partTraceway projectFrameworkWhat it records
Backend systemOne backend projectOpenTelemetryEndpoints, spans, issues, background tasks, AI traces, logs, application metrics, and host metrics
Browser applicationSeparate project per deployed browser appReact, Svelte, Vue.js, or jQueryBrowser errors, web vitals, session replay, distributed-trace linkage, and source-mapped stacks
Mobile applicationSeparate project per independently released appFlutter, React Native, Android, or iOSMobile errors and crashes, replay where supported, and symbolicated stacks
Full-stack JavaScript applicationBackend and browser projectsOpenTelemetry + browser frameworkServer telemetry stays in the backend project; browser telemetry stays in the browser project

Do not send browser or mobile telemetry to the backend project. Those runtimes use different SDKs, build artifacts, and dashboard behavior.

The framework picker offers exactly nine options, and every backend takes the same one:

GroupOptions
BackendOpenTelemetry
BrowserReact, Svelte, Vue.js, jQuery
MobileFlutter, React Native, Android, iOS

There is no Gin, Django, Laravel, or Hono entry, because the language and web framework are chosen later on the project's Connection page, which then shows the exact install and exporter setup. A meta-framework picks the framework it renders with: Next.js and Remix select React, SvelteKit selects Svelte, Nuxt selects Vue.js.

Organizations

Projects live inside an organization, which is the boundary for everything that is not telemetry: members and roles, dashboards, teams, on-call schedules, escalation policies, and status pages. It is also what the organization overview summarizes, putting every server, issue, monitor, and open page across all of the organization's projects one sidebar click apart.

Split by project first. A second organization is right when two groups of projects should share no members, no dashboards, and no on-call rotation, an agency's separate clients for example. Splitting one fleet across organizations costs you the single view of it.

Keep Backend Signals Together

The main backend project should receive all server-side signals:

  • HTTP endpoints and their child spans
  • Queue consumers, scheduled work, and CLI tasks
  • AI and LLM spans
  • Exceptions and OTel logs
  • Application and runtime metrics
  • Host CPU, memory, disk, filesystem, network, and process metrics from the Traceway OTel Agent, or from the Kubernetes collectors when the backend runs in a cluster

APIs, workers, schedulers, and the host agent use the same backend project token. Give each process or host a stable service.name so it remains filterable inside the project:

checkout-api
checkout-worker
checkout-scheduler
checkout-prod-host-1

Create separate backend projects only when the services are separate products or require different ownership, access control, compliance, or data isolation. A different deployment process alone is not a reason to split them.

Browser and Mobile Boundaries

Create one project for each independently deployed browser application. Its framework selection drives the browser SDK setup on the Connection page, and its dedicated upload token keeps source maps scoped to that application.

Create one project for each independently released mobile application. A Flutter product that ships to both Android and iOS normally uses one Flutter project. Separate native Android and iOS applications use separate projects and credentials.

A full-stack framework such as Next.js, SvelteKit, or Remix needs two projects only when its server runs meaningful production code:

  • OpenTelemetry project for API routes, server rendering, workers, tasks, AI calls, and server metrics
  • Browser-framework project for code running in the user's browser

For Next.js, the server half is covered by the Next.js OpenTelemetry guide and the browser half by the React SDK. Each half uses its own project token.

A static export with an external API needs only the browser project; the external API belongs to its backend project.

Create the Projects

For each application boundary:

  1. Open your Traceway dashboard.
  2. Open the project selector in the header and select Add Project.
  3. Choose the organization.
  4. Enter a name that identifies the product and runtime, such as Acme Backend, Acme Web, or Acme Mobile.
  5. Select the framework:
    • OpenTelemetry for the backend, regardless of language or HTTP framework; it is the only backend option, and the preselected default
    • React, Svelte, Vue.js, or jQuery for a browser project
    • Flutter, React Native, Android, or iOS for a mobile project
  6. Select New Project.
  7. Save the project token and open Go to Connection for the tailored setup. For a backend project, the Connection page asks for your language and web framework there and then shows the matching install commands.

Repeat until every deployed browser app and independently released mobile app has its own project. Do not reuse the backend token for them.

Credentials

CredentialPurposeWhere it belongs
Backend project tokenAuthenticates OTLP traces, metrics, and logsBackend deployment secret
Browser connection stringAuthenticates browser SDK reportsPublic build-time browser configuration; never reuse the backend token
Mobile connection stringAuthenticates mobile SDK reportsMobile build configuration; never reuse another project's token
Upload tokenUploads source maps, Flutter symbols, iOS dSYMs, or Android R8 mappingsCI secret; never embed it in the application

Generate an upload token from the project's Connection page under Source Maps or Symbol Upload. Upload tokens are project-specific. Regenerating one invalidates the previous value, so update the corresponding CI secret immediately.

Use component-specific environment variables for runtime credentials so a monorepo cannot accidentally cross-wire projects:

TRACEWAY_BACKEND_TOKEN
PUBLIC_TRACEWAY_WEB_CONNECTION_STRING
TRACEWAY_MOBILE_CONNECTION_STRING

Browser frameworks require their public prefix: for example VITE_ in Vite, PUBLIC_ in SvelteKit, and NEXT_PUBLIC_ in Next.js.

Upload tokens are the exception: each uploader reads one fixed variable name.

UploaderToken variable
traceway-sourcemaps (JavaScript source maps)TRACEWAY_SOURCEMAP_TOKEN
dart run traceway:upload_symbols (Flutter)TRACEWAY_UPLOAD_TOKEN
iOS dSYM uploadTRACEWAY_UPLOAD_TOKEN
com.tracewayapp.symbols Gradle plugin (Android)TRACEWAY_UPLOAD_TOKEN

All of them also read TRACEWAY_URL. Name the CI secret exactly what the uploader reads, or keep a per-component name and pass it explicitly:

traceway-sourcemaps --url "$TRACEWAY_URL" --token "$TRACEWAY_WEB_UPLOAD_TOKEN" --directory ./dist

If one repository releases two mobile apps, their tokens collide on TRACEWAY_UPLOAD_TOKEN. Scope the secret per CI job, or pass --token per build. Upload tokens never use a public prefix and never ship inside the application.

Example Monorepo

For a repository containing a Go API, a Svelte dashboard, one shared worker binary, and a Flutter application, create three projects:

ProjectFrameworkReporters
Acme BackendOpenTelemetryGo API, worker, scheduler, AI model calls, OTel Agent
Acme WebSvelteSvelte browser SDK and source-map upload job
Acme MobileFlutterFlutter SDK and symbol-upload job when release builds are obfuscated

The API and worker use different service.name values but the same backend project token. This keeps an endpoint, its queued task, its AI calls, and the affected server metrics in the same project.

Next Steps