Fandry UI
npm

Getting started with LWR / LWC OSS

Install one npm package, point your project at it, and use <fandry-*> components. Your bundler ships only the ones you use.

Requirements

Link to section Requirements
  • Node.js 18 or newer

  • An LWR or LWC OSS project using lwc 8.x (lwc is a peer dependency, so Fandry uses your copy)

  • npm, or pnpm / yarn if you prefer

1. Install

Link to section 1. Install

One package brings every component and its single third-party dependency (@tanstack/table-core, used by fandry-table). There is nothing else to install.

Terminal
npm install fandryui
​

2. Initialize

Link to section 2. Initialize

The CLI detects your project from lwr.config.json or lwc.config.json and registers the package as a module source. You can also make this edit by hand.

Terminal
npx fandry init
​ lwr.config.json (after)
{
  "lwc": {
    "modules": [
      { "dir": "$rootDir/src/modules" },
      { "npm": "fandryui" }
    ]
  },
  "routes": [ ... ]
}
​

lwc.config.json projects

Plain LWC OSS projects keep the same record at the top level: "modules": [ { "npm": "fandryui" } ].

3. Use a component

Link to section 3. Use a component

The package brings its own fandry namespace, so fandry/button is <fandry-button>. No imports are needed in your template.

src/modules/my/app/app.html
<template>
  <fandry-button onclick={handleSave}>Save</fandry-button>

  <fandry-select
    label="Fruit"
    options={options}
    value={fruit}
    onchange={handleChange}
  ></fandry-select>
</template>
​ src/modules/my/app/app.js
import { LightningElement } from 'lwc';

export default class App extends LightningElement {
  fruit = 'apple';
  options = [
    { label: 'Apple', value: 'apple' },
    { label: 'Banana', value: 'banana' }
  ];

  handleSave() {}
  handleChange(event) {
    this.fruit = event.detail;
  }
}
​

What your project looks like

Link to section What your project looks like Directory structure
my-lwr-app/
├── lwr.config.json            # { "npm": "fandryui" } added by `fandry init`
├── fandry.json                # written by `fandry init`
├── package.json               # "fandryui" in dependencies
├── node_modules/
│   └── fandryui/
│       ├── lwc.config.json    # the public modules ("expose")
│       ├── registry.json
│       └── modules/fandry/    # readable source, one folder per component
│           ├── base/
│           ├── button/
│           ├── select/
│           └── table/ ...
└── src/
    └── modules/
        └── my/
            └── app/           # your code
                ├── app.html
                └── app.js
​

Everything under node_modules/fandryui is readable LWC source. Fandry is not a black box: open a component to see exactly what it does.

Only what you use ships

Link to section Only what you use ships

There is no registry and nothing is registered globally. Your bundler follows the module graph from your templates, so a page that uses fandry-button does not include table, dialog or lookup. There is nothing to add with the CLI on this platform.

Next steps

Link to section Next steps
  • Extend the shared base class: import Base from "fandry/base" gives your own component Fandry's stylesheet and design tokens.

  • Theme by setting any --fd-* token on :root (e.g. --fd-primary: 210 90% 40%; --fd-radius-md: 0), or on one section to theme just that part of the page.

  • Restyle one element inside a component with ::part(), e.g. fandry-link::part(link). Each component page lists its parts.

  • Need a change inside a component that neither CSS nor slots can reach? Copy it into your own namespace and make it yours. Its source is short, plain LWC; keep extends Base and it still follows your tokens.

  • Browse every component, its props and examples under Components.

Build fails with LWC1121 in @lwrjs/loader?

Fresh installs of lwr 0.18.3 can pull @lwc/compiler 9.x, which rejects LWR's own loader. Pin your @lwc/* packages to the same 8.x version as lwc (npm "overrides"). The repository's examples/consumer/package.json shows a working set.

Ready to build? Browse every component, its props and examples under Components.