# Parcel User Guide

Parcel is a **zero configuration build tool for the web**. Point it at an HTML file (or any entry point) and it bundles your JavaScript, TypeScript, CSS, images, and dozens of other asset types into an optimized application — with a built-in dev server, hot reloading, and automatic production optimization. No config file required to get started.

This guide is for developers **using** Parcel to build websites, web apps, and libraries. It covers installation, every command-line option, everyday workflows, and troubleshooting. For architecture, plugin authoring, deployment, and internals, see the **Admin Guide**.

> [!NOTE]
> This guide documents Parcel **v2.16.4**. Parcel requires **Node.js 16 or newer**. The package is published to npm as `parcel`.

---

## Table of Contents

1. [Quick Start](#1-quick-start)
2. [Installation](#2-installation)
3. [The `parcel` Command](#3-the-parcel-command)
4. [Everyday Usage](#4-everyday-usage)
5. [Common Tasks & Recipes](#5-common-tasks--recipes)
6. [The Development Server & Hot Reloading](#6-the-development-server--hot-reloading)
7. [Building for Production](#7-building-for-production)
8. [Working with Different File Types](#8-working-with-different-file-types)
9. [Programmatic API](#9-programmatic-api)
10. [How Parcel Works (Concepts)](#10-how-parcel-works-concepts)
11. [Troubleshooting](#11-troubleshooting)
12. [Frequently Asked Questions](#12-frequently-asked-questions)
13. [Command & Option Reference](#13-command--option-reference)

---

## 1. Quick Start

Get a project running in under a minute. Parcel needs an entry point — usually an HTML file that references your scripts and styles.

**1. Create a project and install Parcel:**

```bash
mkdir my-app && cd my-app
npm install --save-dev parcel
```

**2. Create an entry HTML file** (`src/index.html`) that references a script:

```html
<!DOCTYPE html>
<html>
  <head>
    <title>My App</title>
  </head>
  <body>
    <h1>Hello Parcel</h1>
    <script type="module" src="./app.js"></script>
  </body>
</html>
```

**3. Create the script** (`src/app.js`):

```js
console.log('Bundled by Parcel!');
```

**4. Start the development server:**

```bash
npx parcel src/index.html
```

```text
Server running at http://localhost:1234
✨ Built in 120ms
```

Open `http://localhost:1234` in your browser. Edit `app.js` or `index.html` and the page reloads automatically.

**5. Build for production when you're ready to ship:**

```bash
npx parcel build src/index.html
```

Your optimized output lands in the `dist/` directory.

> [!TIP]
> You did not write a single line of configuration. Parcel detected the HTML entry, found the linked script, compiled it, started a server, and enabled hot reloading — all by default. Configuration only becomes necessary when you outgrow the defaults.

---

## 2. Installation

### Requirements

| Requirement | Detail |
|---|---|
| **Node.js** | Version **16.0.0 or newer** (`engines.node: ">= 16.0.0"`) |
| **Package manager** | npm, Yarn, or pnpm — all supported |
| **OS** | macOS, Linux, Windows (native binaries ship for each; see Troubleshooting) |

### Install into a project

Install Parcel as a development dependency. This is the recommended approach because it pins Parcel's version to your project.

=== "npm"

    ```bash
    npm install --save-dev parcel
    ```

=== "Yarn"

    ```bash
    yarn add --dev parcel
    ```

=== "pnpm"

    ```bash
    pnpm add --save-dev parcel
    ```

### Run it

Once installed, run Parcel through your package manager's runner or via an npm script:

```bash
npx parcel src/index.html
```

A typical `package.json` wires Parcel into named scripts:

```json
{
  "scripts": {
    "start": "parcel src/index.html",
    "build": "parcel build src/index.html"
  }
}
```

```bash
npm start      # development server
npm run build  # production build
```

> [!IMPORTANT]
> Prefer a local (project) install over a global install. A local install guarantees every contributor and CI run uses the exact same Parcel version recorded in your lockfile.

### Scaffolding a new project

Parcel ships an official scaffolding tool (`create-parcel`) that generates a starter project with the standard `start`/`build` scripts already configured.

> [!NOTE]
> If you are starting from scratch, scaffolding a project gives you a sensible directory layout and pre-wired scripts. If you are adding Parcel to an existing project, the manual install above is the right path.

---

## 3. The `parcel` Command

Parcel exposes a single binary, `parcel`, with four subcommands.

| Command | Purpose |
|---|---|
| `parcel serve [input...]` | Start a development server with hot reloading (this is the **default** command) |
| `parcel watch [input...]` | Rebuild on file changes without serving (for embedding in another server) |
| `parcel build [input...]` | Produce an optimized production build |
| `parcel help [command]` | Display help for a command |

### The default command

Running `parcel` with no recognized subcommand is the same as running `parcel serve`. Parcel inspects the first argument; if it is not one of `serve`, `watch`, `build`, or `help`, Parcel inserts `serve` automatically.

```bash
parcel src/index.html
# is equivalent to
parcel serve src/index.html
```

### Entry points

Every command accepts one or more **entry points** (`[input...]`) — files or globs that Parcel should treat as the roots of your application. If you provide none, Parcel uses the current directory (`.`).

```bash
parcel build src/index.html                  # single entry
parcel build src/index.html src/admin.html   # multiple entries
parcel build "src/*.html"                     # glob (quote it so your shell doesn't expand it)
```

> [!TIP]
> Quote glob patterns (`"src/*.html"`). Without quotes your shell expands the glob before Parcel sees it, which produces inconsistent results across shells and operating systems.

### Getting help

```bash
parcel help          # general help
parcel help build    # options for the build command
parcel --help        # same as `parcel help`
parcel --version     # print the Parcel version
```

---

## 4. Everyday Usage

This section walks through the tasks you'll perform daily, grouped by what you're trying to accomplish.

### Start developing

```bash
parcel src/index.html
```

```text
Server running at http://localhost:1234
✨ Built in 340ms
```

Parcel serves your app at `http://localhost:1234`, watches every file in the dependency graph, and reloads the browser (or hot-swaps modules) when you save.

### Pick a different port

The dev server listens on port **1234** by default, or the value of the `$PORT` environment variable.

```bash
parcel src/index.html --port 8080
```

If the requested port is already in use **and you did not specify one explicitly**, Parcel automatically picks the next free port and warns you. If you *did* specify a port that's taken, Parcel fails with an error so the behavior is predictable.

### Open the browser automatically

```bash
parcel src/index.html --open
parcel src/index.html --open firefox   # open a specific browser
```

### Serve over HTTPS

```bash
parcel src/index.html --https                       # auto-generated certificate
parcel src/index.html --https --cert cert.pem --key key.pem   # your own certificate
```

### Rebuild without serving

Use `watch` when another server (e.g. an Express or Rails backend) serves your files and you only need Parcel to keep the bundles fresh:

```bash
parcel watch src/index.html
```

`watch` produces the same output as a build but keeps running and rebuilds incrementally on change. Unlike `build`, it does not minify by default (it runs in development mode).

### Build for production

```bash
parcel build src/index.html
```

`build` runs in **production mode**: minification, scope hoisting, content hashing, and tree shaking are all enabled automatically. Output is written to `dist/`.

### Change the output directory

```bash
parcel build src/index.html --dist-dir build
```

The default output directory is `dist/`.

### Stop a running server

Press **Ctrl+C**. Parcel writes its asset graph to the cache before exiting so the next start is fast.

> [!NOTE]
> While `serve` or `watch` is running in an interactive terminal, Parcel listens for these keyboard shortcuts:
>
> | Keys | Action |
> |---|---|
> | **Ctrl+C** | Gracefully exit (flushes the cache first) |
> | **Ctrl+E** | Start/stop sampling build profiling |
> | **Ctrl+Y** | Take a heap snapshot |

---

## 5. Common Tasks & Recipes

### Build multiple targets at once

If your project defines multiple build targets (for example a modern and a legacy bundle), build a specific one with `--target`:

```bash
parcel build --target modern
parcel build --target modern --target legacy   # repeat the flag for several
```

### Set a public URL / path prefix

When your app is served from a subpath (e.g. `https://example.com/app/`), tell Parcel the prefix so absolute URLs resolve correctly:

```bash
parcel build src/index.html --public-url /app/
```

The default public URL is `/`.

### Disable minification for a readable production build

```bash
parcel build src/index.html --no-optimize
```

### Disable scope hoisting

Scope hoisting concatenates modules for smaller, faster output. Disable it for easier-to-debug bundles:

```bash
parcel build src/index.html --no-scope-hoist
```

### Turn off source maps

Source maps are generated by default in both development and production. Disable them with:

```bash
parcel build src/index.html --no-source-maps
```

### Build async bundles lazily (faster dev startup)

In large apps, `--lazy` defers building async (dynamically imported) bundles until the browser actually requests them. This dramatically speeds up the initial dev server start.

```bash
parcel serve src/index.html --lazy
parcel serve src/index.html --lazy "pages/**"          # only lazily build matching entries
parcel serve src/index.html --lazy --lazy-exclude "admin/**"   # exclude some from lazy mode
```

> [!WARNING]
> `--lazy-exclude` can only be used together with `--lazy`. Lazy bundling is a development-server feature — it is not compatible with content hashing (see Troubleshooting).

### Get a detailed build report

```bash
parcel build src/index.html --detailed-report          # top 10 assets per bundle
parcel build src/index.html --detailed-report 25        # top 25
```

This prints per-asset timings and sizes so you can find what's bloating your bundles.

### Profile a slow build

```bash
parcel build src/index.html --profile   # sampling CPU profile
parcel build src/index.html --trace      # detailed build trace (uses the tracer reporter)
```

### Use a custom config or cache location

```bash
parcel build src/index.html --config ./my-parcelrc.json
parcel build src/index.html --cache-dir .cache
```

### Disable the cache (force a clean build)

```bash
parcel build src/index.html --no-cache
```

> [!CAUTION]
> Disabling the cache makes every build start from scratch and is significantly slower. Use it only when you suspect a stale-cache bug — not as a routine flag.

### Quiet or verbose output

```bash
parcel build src/index.html --log-level error     # only errors
parcel build src/index.html --log-level verbose    # everything
```

Valid levels: `none`, `error`, `warn`, `info`, `verbose`.

---

## 6. The Development Server & Hot Reloading

### What you get for free

When you run `parcel serve` (or just `parcel`), Parcel:

- Serves your app at `http://localhost:1234`
- Watches every file in the dependency graph
- **Hot Module Replacement (HMR)** — swaps changed modules in the running page without a full reload where possible
- Shows a built-in **error overlay** in the browser when a build fails
- Falls back to a full page reload when a module can't be hot-swapped

### Hot reloading options

| Flag | Effect |
|---|---|
| `--no-hmr` | Disable hot module replacement entirely |
| `--hmr-port <port>` | Port for the HMR socket (defaults to `$HMR_PORT`, else the server port) |
| `--hmr-host <host>` | Host for the HMR socket (defaults to `$HMR_HOST`, else the server host) |

```bash
parcel serve src/index.html --no-hmr          # plain reload, no HMR
parcel serve src/index.html --hmr-port 12345
```

### Host, CORS, and stdin

```bash
parcel serve src/index.html --host 0.0.0.0     # listen on all interfaces (default behavior)
parcel serve src/index.html --no-cors           # disable CORS headers
parcel serve src/index.html --watch-for-stdin   # exit automatically when stdin closes
```

> [!TIP]
> `--watch-for-stdin` is useful when Parcel is launched as a child process by another tool — the server shuts down cleanly when the parent process closes the pipe.

### Choosing a file-watcher backend

Parcel watches the filesystem to know when to rebuild. The available backends depend on your OS:

| OS | Available `--watch-backend` values |
|---|---|
| macOS | `brute-force`, `watchman`, `fs-events` |
| Linux | `brute-force`, `watchman`, `inotify` |
| Windows | `brute-force`, `watchman`, `windows` |
| FreeBSD/OpenBSD | `brute-force`, `watchman` |

```bash
parcel serve src/index.html --watch-backend watchman
```

By default Parcel picks the best native backend for your platform.

```bash
parcel serve src/index.html --watch-dir /path/to/project    # set the watch root
parcel serve src/index.html --watch-ignore .git,dist        # directories to ignore
```

The watch root defaults to the nearest lockfile or source-control directory; `--watch-ignore` defaults to `.git` and `.hg`.

> [!IMPORTANT]
> On Linux, editing a watched file can stop triggering rebuilds unless **Watchman** is installed (a known limitation). If hot reloading stops working on Linux, install Watchman or pass `--watch-backend watchman`.

---

## 7. Building for Production

`parcel build` is tuned for shipping. These optimizations are **on by default** in build mode:

| Optimization | Default | Disable with |
|---|---|---|
| Minification (JS/CSS/HTML) | on | `--no-optimize` |
| Scope hoisting (module concatenation + tree shaking) | on | `--no-scope-hoist` |
| Content hashing (cache-busting filenames) | on | `--no-content-hash` |
| Source maps | on | `--no-source-maps` |
| Filesystem cache | on | `--no-cache` |
| Auto-install of missing plugins | on | `--no-autoinstall` |

> [!NOTE]
> In `build` mode, `NODE_ENV` defaults to `production` (overridable). In `serve`/`watch` mode it defaults to `development`. This value is exposed to your code and to any JS-based config.

### A typical production build

```bash
NODE_ENV=production parcel build src/index.html
```

```text
✨ Built in 4.21s

dist/index.html              1.2 KB    312ms
dist/index.4f8a2c.js        148 KB    1.8s
dist/index.9b1e7d.css        22 KB    140ms
```

### Continuous Integration

In CI, Parcel automatically disables auto-install (it detects the `CI` environment variable in build mode), so a missing plugin fails the build instead of silently installing packages.

```bash
# In CI, install deps first, then build deterministically:
npm ci
npm run build
```

> [!TIP]
> Commit your lockfile and run `npm ci` (not `npm install`) in CI. Combined with Parcel's content hashing, this gives byte-stable, reproducible production output.

### Exit codes

| Code | Meaning |
|---|---|
| `0` | Build succeeded |
| `1` | Build failed (diagnostics were printed) |
| `130` | Interrupted with Ctrl+C during a `build` |

---

## 8. Working with Different File Types

Parcel understands a huge range of file types out of the box — no plugins to install for the common cases. It picks the right compiler based on the file extension.

### Supported out of the box

| Category | Extensions handled by default |
|---|---|
| **Markup** | `.html`, `.htm`, `.xhtml`, `.pug` |
| **Scripts** | `.js`, `.mjs`, `.cjs`, `.jsx`, `.ts`, `.tsx`, `.es6`, `.jsm`, `.coffee`, `.mdx` |
| **Styles** | `.css`, `.pcss`, `.scss`, `.sass`, `.less`, `.styl`, `.stylus`, `.sss` |
| **Data** | `.json`, `.json5`, `.jsonld`, `.toml`, `.yaml`, `.yml` |
| **Images** | `.png`, `.jpg`, `.jpeg`, `.webp`, `.gif`, `.tiff`, `.avif`, `.heic`, `.heif`, `.svg` |
| **Frameworks** | `.vue`, `.elm` |
| **Other** | `.graphql`/`.gql`, `.glsl`/`.vert`/`.frag`, `.xml`/`.rss`/`.atom`, `.node`, `.webmanifest` |

> [!TIP]
> TypeScript and JSX **just work** — no `tsconfig`-driven build step or Babel preset required. Import a `.ts` or `.tsx` file and Parcel compiles it. Parcel's JavaScript/TypeScript compiler is written in Rust for native speed.

### Importing assets

Import any supported asset directly from your JavaScript and Parcel wires up the dependency:

```js
import './styles.css';            // bundled and injected
import logo from './logo.png';    // logo === the output URL of the optimized image
import data from './config.toml'; // parsed to a JS object
```

### Named import pipelines

Parcel supports special URL-scheme prefixes on imports to control *how* an asset is processed:

| Prefix | Effect |
|---|---|
| `url:` | Import the asset's URL instead of its contents (e.g. `import url from 'url:./file.pdf'`) |
| `bundle-text:` | Inline the bundled output of an asset as a string |
| `data-url:` | Inline the asset as a base64 data URL |
| `worklet:` | Treat the script as a worklet entry |
| `react-static:` | Render a React component to static HTML at build time |
| `types:` | Bundle TypeScript type declarations (`.d.ts`) |

```js
import workerUrl from 'url:./worker.js';
import iconDataUrl from 'data-url:./icon.svg';
```

### Code splitting

Use a dynamic `import()` to create a separate bundle that loads on demand. Parcel does the splitting automatically:

```js
button.addEventListener('click', async () => {
  const { renderChart } = await import('./chart.js'); // becomes its own bundle
  renderChart();
});
```

> [!TIP]
> Combine dynamic imports with the dev-server `--lazy` flag so those split bundles are only built when first requested — keeping cold-start times low in large apps.

---

## 9. Programmatic API

Beyond the CLI, Parcel exposes a JavaScript API via the `@parcel/core` package. Use it to embed Parcel in your own tooling.

### A one-shot build

```js
import {Parcel} from '@parcel/core';

const bundler = new Parcel({
  entries: 'src/index.html',
  defaultConfig: '@parcel/config-default',
  mode: 'production',
});

try {
  const {bundleGraph, buildTime} = await bundler.run();
  const bundles = bundleGraph.getBundles();
  console.log(`✨ Built ${bundles.length} bundles in ${buildTime}ms!`);
} catch (err) {
  // Build failures are thrown as a BuildError
  console.error(err.diagnostics);
}
```

`run()` resolves with a **build-success event** (containing the bundle graph, changed assets, and build time) or throws a `BuildError` whose `diagnostics` describe what went wrong.

### Watch mode

```js
import {Parcel} from '@parcel/core';

const bundler = new Parcel({
  entries: 'src/index.html',
  defaultConfig: '@parcel/config-default',
});

const subscription = await bundler.watch((err, event) => {
  if (err) throw err;
  if (event.type === 'buildSuccess') {
    console.log(`✨ Built ${event.bundleGraph.getBundles().length} bundles`);
  } else if (event.type === 'buildFailure') {
    console.error(event.diagnostics);
  }
});

// later, to stop watching:
await subscription.unsubscribe();
```

### Public exports

The `@parcel/core` package exports:

| Export | Purpose |
|---|---|
| `Parcel` (also the default export) | The bundler class |
| `BuildError` | Error thrown by `run()` on build failure; carries `diagnostics` |
| `createWorkerFarm` | Create a reusable worker farm to share across multiple `Parcel` instances |

> [!NOTE]
> `new Parcel(options)` is cheap — the heavy initialization (loading config, starting the worker farm, opening the cache) happens lazily on the first `run()` or `watch()` call.

---

## 10. How Parcel Works (Concepts)

You don't need this section to use Parcel, but understanding the model helps you reason about builds.

### Zero configuration

Parcel ships a **default configuration** (`@parcel/config-default`) that maps every supported file extension to the right compiler. You only create a `.parcelrc` when you need to add or replace a plugin. (The full plugin pipeline and how to customize it is documented in the **Admin Guide**.)

### The asset pipeline

Every file flows through a series of plugin stages:

```text
Entry → Resolver → Transformers → Bundler → Namer → Runtimes → Packager → Optimizer → Compressor → (write to dist) → Reporter
```

- **Resolvers** turn an import specifier into a file path.
- **Transformers** compile each asset (TypeScript → JS, Sass → CSS, image optimization, …).
- The **Bundler** groups assets into bundles; **Namers** give them filenames.
- **Packagers** combine a bundle's assets into final output; **Optimizers** minify it.
- **Reporters** surface progress, the dev server, and the error overlay.

### Caching

Parcel caches everything in `.parcel-cache`. Unchanged code is never rebuilt — even across restarts. This is why the second build of a project is dramatically faster than the first.

> [!TIP]
> The cache is safe to delete (`.parcel-cache/`) if you ever suspect corruption. Parcel will simply rebuild from scratch on the next run. Add `.parcel-cache` and `dist` to your `.gitignore`.

### Targets and environments

A **target** describes an output: where it goes (`distDir`), its public URL prefix, and which environments (browsers/Node versions) it must support. The CLI flags `--target`, `--dist-dir`, and `--public-url` set the default target's options; richer per-target configuration lives in your `package.json`. See the **Admin Guide** for the complete target and environment reference.

### Parallelism and native speed

Parcel runs transformations in parallel across a **worker farm** (one worker per CPU core by default) and implements its hottest paths — the JavaScript compiler, the HTML transformer, and the module resolver — in **Rust** for native performance.

---

## 11. Troubleshooting

Each entry lists the cause and the fix. Error messages are quoted exactly as Parcel emits them.

### Error: `Port "1234" could not be used`

**Cause:** You passed `--port` with a value that's already in use by another process.
**Solution:** Choose a free port, or omit `--port` to let Parcel auto-select one.

```bash
parcel serve src/index.html --port 4000
```

**Prevention:** Don't hard-code a port that other dev servers also use; rely on auto-selection during development.

### Error: `Lazy bundling does not work with content hashing`

**Cause:** `--lazy` was combined with content hashing. Lazy-built bundles can't have stable content hashes because they're produced on demand.
**Solution:** Use `--lazy` only with `parcel serve`/`watch` (where content hashing is off by default), or drop `--lazy` for production builds.
**Prevention:** Treat `--lazy` as a development-only speed feature.

### Error: `Initiated Worker with invalid execArgv flags` (`ERR_WORKER_INVALID_EXEC_ARGV`)

**Cause:** A known incompatibility between Parcel's worker farm and certain newer Node.js releases (reported on Node 24.7.0+).
**Solution:** Use a Node.js LTS release that Parcel supports. If you must run a bleeding-edge Node, clear `NODE_OPTIONS` of unsupported worker flags before running Parcel.
**Prevention:** Pin your project to a Node LTS version via `.nvmrc` or `engines`.

### Error: `Failed to load native binding` / `Unsupported architecture on ... ${arch}`

**Cause:** Parcel's prebuilt Rust binary for your OS/CPU architecture was not installed (common on uncommon platforms, in restricted Docker images, or when `optionalDependencies` were skipped).
**Solution:** Reinstall dependencies without skipping optional ones (`npm install` — not `npm install --no-optional`). Ensure your platform/architecture is supported.
**Prevention:** Don't pass `--no-optional` / `--omit=optional` when installing; Parcel's native binaries are delivered as optional dependencies.

### Dev server stops reloading on Linux after editing a file

**Cause:** The default watcher backend can miss edits on some Linux setups (reported issue).
**Solution:** Install **Watchman** and/or pass `--watch-backend watchman`.

```bash
parcel serve src/index.html --watch-backend watchman
```

**Prevention:** Install Watchman as part of your Linux dev environment setup.

### Error: `@parcel/fs tried to access @parcel/core (a peer dependency) but it isn't provided by its ancestors`

**Cause:** Mismatched or partially installed `@parcel/*` packages — usually from mixing Parcel versions or a corrupted install.
**Solution:** Delete `node_modules` and your lockfile, then reinstall so every `@parcel/*` package resolves to the same version.

```bash
rm -rf node_modules package-lock.json && npm install
```

**Prevention:** Keep all `@parcel/*` packages on the same version.

### Error: `Could not get available port`

**Cause:** Parcel could not find any free port to bind the dev server to.
**Solution:** Free up ports, or specify an available one with `--port`.

### Build behaves oddly / picks up stale output

**Cause:** A corrupted or stale cache.
**Solution:** Build once with `--no-cache`, or delete `.parcel-cache/`.

```bash
rm -rf .parcel-cache && parcel build src/index.html
```

### Error: `Neither npm nor yarn found on system`

**Cause:** Parcel's auto-install needs a package manager on `PATH` to install a missing plugin and couldn't find one.
**Solution:** Ensure `npm` or `yarn` is installed and on your `PATH`, or pass `--no-autoinstall` and install the missing package yourself.

### Error: `PostCSS config should be an object.` / `PostCSS config must have plugins`

**Cause:** A malformed PostCSS configuration (`.postcssrc`, `postcss.config.js`, …).
**Solution:** Ensure the config exports an object with a `plugins` field.
**Prevention:** Validate your PostCSS config against the PostCSS documentation.

### Error: `Bundles conflicting names`

**Cause:** Two bundles resolved to the same output filename (reported with service workers in web extensions).
**Solution:** Adjust your entry/target configuration so output names are unique. Check for duplicate entry points producing identically named bundles.

---

## 12. Frequently Asked Questions

**Q: Do I really need zero configuration?**
Yes — for most projects you never write a config file. Parcel's default configuration maps every supported extension to the correct compiler. You only add a `.parcelrc` when you need a plugin that isn't built in. See the Admin Guide for that.

**Q: How do I use TypeScript?**
Just import `.ts`/`.tsx` files. Parcel compiles them with its built-in Rust-based compiler. No Babel preset or separate `tsc` step is needed for bundling. (For emitting `.d.ts` type declarations of a library, the `types:` import pipeline and the TypeScript types transformer handle that.)

**Q: What's the default dev-server port?**
`1234`, or the value of the `$PORT` environment variable. Override with `--port`.

**Q: Where does the output go?**
To `dist/` by default. Change it with `--dist-dir` or per-target configuration in `package.json`.

**Q: How do I make a production build?**
`parcel build <entry>`. Minification, scope hoisting, tree shaking, and content hashing are all enabled automatically.

**Q: What's the difference between `serve` and `watch`?**
`serve` runs a development HTTP server with hot reloading. `watch` rebuilds on change but does **not** serve — use it when another server hosts your files.

**Q: How do I split my code into multiple bundles?**
Use a dynamic `import()`. Parcel automatically creates a separate, on-demand bundle for the imported module.

**Q: Why is my first build slow but later ones fast?**
The first build populates the `.parcel-cache`. Subsequent builds reuse cached results for unchanged files, even across restarts.

**Q: Can I run Parcel from my own Node script?**
Yes — use the `@parcel/core` programmatic API (`new Parcel(options)`, then `run()` or `watch()`). See [Programmatic API](#9-programmatic-api).

**Q: Does Parcel generate source maps?**
Yes, by default, in both development and production. Disable with `--no-source-maps`.

**Q: How do I target specific browsers?**
Define a `browserslist` in your `package.json`, and/or configure targets there. Parcel transforms your code to match. (Full target/environment reference: Admin Guide.)

**Q: How do I add a plugin (e.g. a custom transformer)?**
Create a `.parcelrc` that extends the default config and registers your plugin. The plugin system and authoring guide are in the Admin Guide.

**Q: How do I speed up the dev server for a huge app?**
Use `--lazy` so async bundles are only built when the browser requests them.

**Q: How do I see what's making my bundle large?**
Run `parcel build --detailed-report` for per-asset sizes and timings.

**Q: Is Parcel free?**
Yes. Parcel is open source under the **MIT license**.

---

## 13. Command & Option Reference

### Commands

| Command | Description |
|---|---|
| `parcel serve [input...]` | Start a development server (default command) |
| `parcel watch [input...]` | Rebuild on change without serving |
| `parcel build [input...]` | Bundle for production |
| `parcel help [command]` | Show help for a command |

### Options by command

`✓` = available on that command.

| Option | serve | watch | build | Description |
|---|:---:|:---:|:---:|---|
| `--public-url <url>` | ✓ | ✓ | ✓ | Path prefix for absolute URLs (default `/`) |
| `--open [browser]` | ✓ | | | Open the app in a browser after start |
| `--watch-for-stdin` | ✓ | ✓ | | Exit when stdin closes |
| `--lazy [includes]` | ✓ | | | Build async bundles on demand (optionally limited to matching globs) |
| `--lazy-exclude <excludes>` | ✓ | | | Globs to exclude from lazy building (requires `--lazy`) |
| `--no-content-hash` | | ✓ | ✓ | Disable content hashing in output filenames |
| `--no-optimize` | | | ✓ | Disable minification |
| `--no-scope-hoist` | | | ✓ | Disable scope hoisting |

### HMR / dev-server options (serve and watch)

| Option | Description |
|---|---|
| `--no-hmr` | Disable hot module replacement |
| `-p, --port <port>` | Server port (default `$PORT` or `1234`) |
| `--host <host>` | Host to listen on (default: all interfaces) |
| `--https` | Serve over HTTPS |
| `--cert <path>` | Certificate to use with HTTPS |
| `--key <path>` | Private key to use with HTTPS |
| `--hmr-port <port>` | HMR socket port (default `$HMR_PORT`) |
| `--hmr-host <host>` | HMR socket host (default `$HMR_HOST`) |
| `--no-cors` | Disable CORS headers |

### Common options (all of serve, watch, build)

| Option | Description |
|---|---|
| `--no-cache` | Disable the filesystem cache |
| `--config <path>` | Config to use — a path or a package name |
| `--cache-dir <path>` | Cache directory (default `.parcel-cache`) |
| `--watch-dir <path>` | Root watch directory (default: nearest lockfile / VCS dir) |
| `--watch-ignore [path]` | Comma-separated dirs to ignore (default `.git`, `.hg`) |
| `--watch-backend <name>` | File-watcher backend (OS-specific; see §6) |
| `--no-source-maps` | Disable source maps |
| `--target [name]` | Only build the given target(s); repeatable |
| `--log-level <level>` | `none`, `error`, `warn`, `info`, or `verbose` |
| `--dist-dir <dir>` | Output directory when not set by a target (default `dist`) |
| `--no-autoinstall` | Disable automatic installation of missing plugins |
| `--profile` | Enable sampling build profiling |
| `--trace` | Enable build tracing |
| `--detailed-report [count]` | Print asset timings/sizes (default top 10) |
| `--reporter <name>` | Run an additional reporter; repeatable |
| `--feature-flag <name=value>` | Set a feature flag |
| `-V, --version` | Print the version number |

### Environment variables

| Variable | Effect |
|---|---|
| `PORT` | Default dev-server port |
| `HMR_PORT` | Default HMR socket port |
| `HMR_HOST` | Default HMR socket host |
| `NODE_ENV` | `production` for build, `development` otherwise (overridable); exposed to your code |
| `CI` | When set, disables auto-install during `build` |
| `PARCEL_WORKERS` | Number of worker threads to spawn |
| `PARCEL_MAX_CONCURRENT_CALLS` | Max concurrent calls per worker |
| `PARCEL_WORKER_BACKEND` | Worker backend (`threads` or `process`) |
| `PARCEL_INCREMENTAL_BUNDLING` | Set to `false` to disable incremental bundling |
| `NODE_OPTIONS` | Passed through to worker processes |

### Interactive keys (while serving/watching in a TTY)

| Keys | Action |
|---|---|
| `Ctrl+C` | Graceful exit (writes cache first) |
| `Ctrl+E` | Toggle build profiling |
| `Ctrl+Y` | Take a heap snapshot |

### Defaults at a glance

| Setting | Default |
|---|---|
| Dev-server port | `1234` (or `$PORT`) |
| Output directory | `dist/` |
| Cache directory | `.parcel-cache/` |
| Public URL | `/` |
| Source maps | enabled |
| Minify / scope hoist / content hash (build) | enabled |
| Auto-install | enabled (disabled in CI for builds) |
| Entry when none given | `.` (current directory) |

---

_Generated June 2026 from parcel-bundler/parcel at 5948485. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
