Work top to bottom. Always mirror an existing sibling library (e.g.
avatar) for exact file structure and config; do not invent new patterns.
-
Pick a sibling to mirror. Choose the closest existing library under
libs/components/ and open its project.json, ng-package.json,
package.json, tsconfig*.json, karma.conf.js, src/index.ts,
documentation.json, and testing/ folder. You will copy this structure.
-
Scaffold the library. Run the generator (note: --name is required;
the generator rejects a positional name):
npx nx g @nx/angular:library \
--name=<library> \
--directory=libs/components/<library> \
--publishable \
--importPath=@skyux/<library> \
--prefix=sky \
--unitTestRunner=none \
--tags=component,npm \
--standalone=false \
--skipModule \
--skipFormat \
--no-interactive
This produces project.json, ng-package.json, package.json,
tsconfig.json, tsconfig.lib.json, tsconfig.lib.prod.json,
src/index.ts, the @skyux/<library> path mapping, and an
eslint.config.cjs. Then reconcile it to the sibling:
- Revert generator churn first.
git checkout -- nx.json .prettierignore,
delete the stray root project.json the generator created, and undo
the array reformatting it applied to tsconfig.base.json (keep only the
new @skyux/<library> mapping).
project.json — add the Karma test target (Karma executor, theme
styles libs/components/theme/src/lib/styles/sky.scss and
.../themes/modern/styles.scss, codeCoverage: true,
codeCoverageExclude: ["**/fixtures/**"], and the ci configuration);
give lint the lintFilePatterns for src/**/*.ts and src/**/*.html;
hardcode outputs to dist/libs/components/<library>; add the build
dependsOn peers as needed. Remove the generator's release and
nx-release-publish blocks (siblings do not use them).
ng-package.json — add styleIncludePaths: ["../../.."] and
inlineStyleLanguage: "scss". Add allowedNonPeerDependencies for any
third-party runtime dependency (see step 2a).
package.json — change version to 0.0.0-PLACEHOLDER; pin every
@skyux/*/@skyux-sdk/* peer dependency to 0.0.0-PLACEHOLDER; add the
author, keywords, license, repository, bugs, and homepage
fields and the tslib dependency from the sibling. sideEffects stays
false.
karma.conf.js and tsconfig.spec.json — copy from the sibling
(the generator omits these because --unitTestRunner=none).
eslint.config.cjs — replace with eslint.config.js containing
const config = require('../../../eslint-libs.config'); module.exports = config;.
2a. Declare third-party dependencies (e.g. a charting or formatting lib).
-
Create the public API barrel. Add src/index.ts. Every public export
MUST be prefixed with sky/Sky. Export new components and directives by
their own name
(e.g. export { SkyThingComponent } from './lib/.../thing.component';), not
under an obscured as λN alias. Some existing libraries still export older
components/directives under λ aliases; that is a legacy pattern — do NOT
replicate it for new exports.
-
Create the testing entry point. Mirror the sibling's testing/
folder: its project.json (project name <library>-testing, tag
testing), ng-package.json, tsconfig*.json, karma.conf.js, and
src/public-api.ts barrel. This produces @skyux/<library>/testing.
-
Defer documentation.json to the first component. Do not create it
for the empty scaffold. Its schema
(documentation-schema.json)
requires development.docsIds (at least one entry) and a primaryDocsId,
so a valid file cannot exist until the suite has a documented type. The
add-skyux-component skill creates it
alongside the first component.
-
Generate i18n resources (only if the library needs them). If the
library ships translatable strings, set up src/assets/locales like the
sibling, then regenerate the resources module:
npm run dev:create-library-resources
Skip this step for libraries with no localized strings.
-
Verify the empty library builds, lints, and formats. Before adding
components, confirm the scaffold is sound:
npx nx build <library>
npx nx lint <library>
npx nx lint <library>-testing
npx nx format:write --projects=<library>,<library>-testing
Do not gate on nx test <library> yet: an empty library has no spec
files, so Karma exits with "Executed 0 of 0". The test gate becomes
meaningful once the first component (with a spec) lands in the next step.
-
Add the first component. Hand off to
add-skyux-component to add the suite's
first component, harness, unit tests, visual tests, and code example. The
companion e2e/storybook app is created during the visual-tests step via
add-component-visual-tests.
-
Commit. Use a Conventional Commit with the components/<library>
scope per
commit-message.instructions.md.