Stencil Output Targets: When to Split Your Component Bundle
Stencil's build configuration controls whether components ship as one bundle or individually loadable files. Learn how to configure dist-custom-elements and verify the result.
27 Sept 2026, 07:10 UTC

The Monolithic Bundle Problem
You have built a handful of Stencil components, run the default build, and discovered that every consumer now downloads the entire component library—even if they only use one button. The useful takeaway is that Stencil's output target configuration, not the component code itself, controls whether your build produces a single bundle or a set of independently loadable custom element bundles.
Understanding Stencil's Output Targets
Stencil compiles TypeScript and JSX into standard Web Components, but the build step also decides how those components are packaged. The default www output target generates a static site with a single bundled script, which is convenient for demos but inefficient for distribution. The dist output target produces a library bundle intended for consumption as an npm package. The dist-custom-elements output target emits one bundle per component, letting the browser fetch only what the page actually uses.
Configuring dist-custom-elements for Lazy Loading
Suppose you maintain a design system with twelve components, but most pages only use two. In your stencil.config.ts file at the project root, replace the default output target with a custom-elements configuration:
import { Config } from '@stencil/core';
export const config: Config = {
namespace: 'my-design-system',
outputTargets: [
{
type: 'dist-custom-elements',
dir: 'dist/custom-elements',
externalRuntime: false
}
]
};
Run the build from your terminal in the project root. No elevated permissions are required:
npm run build
After the build completes, inspect the dist/custom-elements directory. You should see separate JavaScript files such as my-button.js and my-input.js rather than one large index.js. If you still see a single bundle, verify that no other output target is overriding the configuration.
Choosing the Right Target: A Diagnostic Comparison
| Scenario | Recommended Target | Trade-off |
|---|---|---|
| Internal demo or documentation site | www | Fast to set up; ships every component in one request. |
| Design system consumed as an npm package | dist | Single entry point; consumers bundle everything together. |
| Micro-frontend or CDN distribution | dist-custom-elements | More HTTP requests, but each page loads only the components it uses. |
Limits and Verification
This approach assumes your consumers can handle dynamic custom element registration. If your host application uses server-side rendering without hydration support, the extra network requests may delay first paint. Also, the exact output directory structure and file names can vary between Stencil CLI versions, so treat the paths above as placeholders rather than guaranteed constants.
Practical check: Open the generated dist/custom-elements folder and count the JavaScript files. If the count matches your component count, the split build succeeded. Then load a plain HTML page that imports only my-button.js and confirm in the browser's Network tab that no other component bundles were fetched.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.