parcel-bundler/parcel · error · ThrowableDiagnostic

Library targets are not supported in serve mode.

Error message

Library targets are not supported in serve mode.

What it means

Parcel's serve (dev-server) mode resolves a single browser target from package.json. When the only resolved target is a library target (one whose env.isLibrary is true, e.g. "main"/"module"/"browser" fields that point at a library build), TargetRequest refuses to serve it because library targets emit consumable artifacts, not runnable app bundles. The diagnostic is thrown only in serve mode when no explicit target was given and every target is browser-context and the lone target is a library.

Source

Thrown at packages/core/core/src/requests/TargetRequest.js:378

        });

      // Explicit targets were not provided. Either use a modern target for server
      // mode, or simply use the package.json targets.
      if (
        this.options.serveOptions &&
        targets.every(t => BROWSER_ENVS.has(t.env.context))
      ) {
        // In serve mode, we only support a single browser target. Since the user
        // hasn't specified a target, use one targeting modern browsers for development
        let distDir = toProjectPath(
          this.options.projectRoot,
          this.options.serveOptions.distDir,
        );
        let mainTarget = targets.length === 1 ? targets[0] : null;

        if (mainTarget?.env.isLibrary) {
          let loc = mainTarget.loc;
          throw new ThrowableDiagnostic({
            diagnostic: {
              origin: '@parcel/core',
              message: md`
Library targets are not supported in serve mode.
              `,
              codeFrames: loc
                ? [
                    {
                      filePath: fromProjectPath(
                        this.options.projectRoot,
                        loc.filePath,
                      ),
                      codeHighlights: [
                        convertSourceLocationToHighlight(
                          loc,
                          'Target declared here',
                        ),
                      ],

View on GitHub (pinned to 59484858a1)

Solutions

  1. Remove or rename the library target field (e.g. delete `main`/`module`) so Parcel treats the package as an app, or add an explicit app source entry.
  2. Run serve with an explicit non-library target, e.g. `parcel serve src/index.html --target default`.
  3. If this is genuinely a library, use `parcel build` instead of `parcel serve`.

Example fix

// before (package.json)
{
  "name": "my-lib",
  "main": "dist/index.js",
  "targets": { "main": { "isLibrary": true } }
}
// $ parcel serve

// after (package.json) — treat as app
{
  "name": "my-app",
  "source": "src/index.html"
}
// $ parcel serve src/index.html
Defensive patterns

Strategy: validation

Validate before calling

import { readFileSync } from 'fs';
function assertServeSafe(pkgPath) {
  const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
  const libFields = ['main','module','browser'];
  const isLibTarget = (f) =>
    pkg.targets?.[f]?.isLibrary === true ||
    (libFields.includes(f) && pkg[f] && !pkg.source && !pkg.entries);
  if (libFields.some(isLibTarget)) {
    throw new Error('Cannot serve: package.json declares only library targets. Add a `source` field or use `parcel build`.');
  }
}

Type guard

function isLibraryTargetDescriptor(d) {
  return d != null && (d.isLibrary === true || d.outputFormat === 'global');
}

Try / catch

try {
  const b = new Parcel({ entries, serveOptions: { port } });
  await b.run();
} catch (e) {
  if (/Library targets are not supported in serve mode/.test(e.message)) {
    console.error('Use `parcel build` for libraries, or add an app `source` field.');
  } else throw e;
}

Prevention

When it happens

Trigger: Running `parcel serve` (or the dev server) against a package whose package.json only defines library-style output fields (main/module/browser) that resolve to a library env, without passing an explicit `--target`.

Common situations: A library package misused as an application; pointing a dev server at a package designed to be published rather than served; migrating an app that accidentally declares `main` to a library output format; forgetting to add an `entries`/source field while only having `main`/`module`.

Related errors


AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13). Data as JSON: /api/errors/c7e385e4f26e2ae9. Report an issue: GitHub.