GuideAdded in v16.4

Eject a component

Copy one component's source into your app and own it. The rest stays on npm.

When to eject

When a token, a hook or a template slot cannot get you there. Try those first: a copy stops getting updates.

Eject one component, not the library. A changed template, a different DOM structure or behaviour the inputs do not cover are good reasons. A colour or a size is not: see Theming.

The command

It reads the installed version and copies the sources of that release.

ng g ngwr:eject button
OptionWhat it does
<entry>The path under ngwr/: button, select, charts/bar-chart. A bare bar-chart works too
--pathWhere the copy goes. Default: src/app/ngwr/<entry>
--fromA local checkout of the ngwr repository to copy from, for work offline
--dry-runLists the files and writes nothing
ng g ngwr:eject charts/bar-chart --path src/app/ui/bar-chart
ng g ngwr:eject button --dry-run
ng g ngwr:eject button --from ../ngwr

The npm package ships compiled code, so the sources come from GitHub, at the tag of your version. Offline, pass --from with a local checkout.

Then import the copy, and load its stylesheet instead of the package's.

// before
import { WrButton } from 'ngwr/button';

// after
import { WrButton } from './ngwr/button';
// styles.scss
@use 'ngwr/theme';
@use './app/ngwr/button/styles';

What changes

WhatAfter eject
The componentYours. Edit the template, the styles and the class freely
ng updateSkips the copy: no fixes, no migrations, no new inputs
Everything elseStill the package: the copy imports ngwr/utils, ngwr/icon, ngwr/theme
Selector and classesThe same names as the package

Never import the copy and the package's component into the same template: both match the same selector. To use both, rename the selector and the .wr-* classes in the copy.

A few components read private files of ngwr that no package path exposes. The command copies those too, into _ngwr-internal beside the ejected folder. Components ejected side by side share it, and a file already there is left as it is.

Going back

Delete the folder and import from the package again.

rm -r src/app/ngwr/button

Point the imports back at ngwr/button and restore @use 'ngwr/button'; in the stylesheet. Updates reach the component again. Once no ejected component is left, delete _ngwr-internal too.

See also