[](https://www.npmjs.com/package/@hmcts/opal-frontend-common) [](https://github.com/hmcts/opal-frontend-common-ui-l
npm install @hmcts/opal-frontend-common



This is an Angular Library.
- Getting Started
- Development server
- Build
- Switching Between Local and Published Versions
- Running unit tests
- Angular code scaffolding
- Commonly Used Commands
- Using This Library
- Publishing the Library
Running the application requires the following tools to be installed in your environment:
- Node.js v23.7.0 or later
- yarn v4
Install dependencies by executing the following command:
``bash
yarn
`
Run yarn ng build to build the project. The build artifacts will be stored in the dist/ directory.
See opal-frontend for how this library is consumed in practice.
Use the yarn import:local:common-ui-lib and yarn import:published:common-ui-lib scripts in your consuming project (opal-frontend) to switch between local development and the published npm version of the library.
To use a published version of this library during development in another project:
1. In the consuming project, run:
`bash`
yarn import:published:common-ui-lib
To use a local version of this library during development in another project:
1. Build this library:
`bash`
yarn build
2. In your consuming project (e.g. opal-frontend), ensure you have set an environment variable pointing to the local build:
`bash`
# In your shell config file (.zshrc, .bash_profile, or .bashrc)
export COMMON_UI_LIB_PATH="[INSERT PATH TO COMMON UI LIB FOLDER]"
3. In the consuming project (e.g. opal-frontend), run:
`bash`
yarn import:local:common-ui-lib
This will remove the published version and install the local build using the path provided.
4. To switch back to the published version:
`bash`
yarn import:published:common-ui-lib
This setup makes it easy to switch between development and production versions of the shared library.
Once any changes have been approved and merged into the main branch, you'll need to publish a new version of the library so that it can be consumed by other projects. To do this:
1. Increment the version number in both the library's root package.json and in /projects/opal-frontend-common/package.json.
2. Commit and push those changes to the main branch.
3. On GitHub, create a new release and use the updated version number as a tag.
4. When the release workflow completes, the library will be published.
After this new version of the library is published, any consuming application should remove the local or outdated version of the library and then install the published version by running:
`bash`
yarn import:published:common-ui-lib
Run yarn test to execute the unit tests via karma.
To check code coverage, run yarn test:coverage to execute the unit tests via karma but with code coverage.
The coverage report will be available in the coverage/ directory (e.g. coverage/index.html).
This library uses the prefix opal-lib for all of its shared components, as specified in the angular.json file. When generating new components, make sure they are prefixed accordingly. This ensures consistent naming and avoids naming collisions across applications.
Run yarn ng generate component component-name to generate a new component. You can also use yarn ng generate directive|pipe|service|class|guard|interface|enum|module.
Note the requirement for prefixing the ng commands with yarn
This library uses multiple entry points, which allows you to organize and expose different parts of the library in separate modules. Each entry point requires:
- An ng-package.json to define how the entry point should be packaged.package.json
- A to specify the entry point's metadata and dependencies.public-api.ts
- A to declare and export the resources for that entry point.
Alias paths need to be set in both the /projects/opal-frontend-common/package.json and the library's tsconfig.json. These aliases help the consuming application import from each entry point using the correct path. By properly defining these aliases, developers can import modules from your library entry points without resorting to complex relative paths.
#### Example Usage of Entry Points
To import a module from a specific entry point in your application:
`ts`
// Example: Importing various items from the library
import { GovukTextInputComponent } from '@hmcts/opal-frontend-common/components/govuk/govuk-text-input';
import { DateService } from '@hmcts/opal-frontend-common/services/date-service';
import { dateOfBirthValidator } from '@hmcts/opal-frontend-common/validators/date-of-birth';
import { hasFlowStateGuard } from '@hmcts/opal-frontend-common/guards/has-flow-state';
import { TitleResolver } from '@hmcts/opal-frontend-common/resolvers/title';
import { GlobalStore } from '@hmcts/opal-frontend-common/stores/global';
The following commands are available in the package.json:
- yarn build dist/
Builds the Angular library and outputs to the folder.
- yarn test
Executes unit tests via karma.
- yarn test:coverage coverage/
Runs unit tests with code coverage reporting enabled. The coverage report can be found in the directory.
- yarn lint
Runs linting using ESLint.
There is a custom lint rule for member ordering to ensure members in the code are ordered in the following format:
`json`
[
"private-static-field",
"protected-static-field",
"public-static-field",
"private-instance-field",
"protected-instance-field",
"public-instance-field",
"constructor",
"private-static-method",
"protected-static-method",
"public-static-method",
"private-instance-method",
"protected-instance-method",
"public-instance-method"
]
- yarn prettier
Checks that all files conform to the Prettier formatting rules.
- yarn prettier:fix
Automatically formats files using Prettier.
https://angular.dev/ai/develop-with-ai
Paste the following prompt into your AI assistant of choice.
`markdown
You are an expert in TypeScript, Angular, and scalable web application development. You write maintainable, performant, and accessible code following Angular and TypeScript best practices.
- Use strict type checking
- Prefer type inference when the type is obvious
- Avoid the any type; use unknown when type is uncertain
- Always use standalone components over NgModules
- Do NOT set standalone: true inside the @Component, @Directive and @Pipe decoratorsNgOptimizedImage
- Use signals for state management
- Implement lazy loading for feature routes
- Use for all static images.@HostBinding
- Do NOT use the and @HostListener decorators. Put host bindings inside the host object of the @Component or @Directive decorator instead
- Keep components small and focused on a single responsibility
- Use input() and output() functions instead of decoratorscomputed()
- Use for derived statechangeDetection: ChangeDetectionStrategy.OnPush
- Set in @Component decoratorngClass
- Prefer inline templates for small components
- Prefer Reactive forms instead of Template-driven ones
- Do NOT use , use class bindings insteadngStyle
- DO NOT use , use style bindings instead
- Use signals for local component state
- Use computed() for derived statemutate
- Keep state transformations pure and predictable
- Do NOT use on signals, use update or set instead
- Keep templates simple and avoid complex logic
- Use native control flow (@if, @for, @switch) instead of ngIf, ngFor, *ngSwitch
- Use the async pipe to handle observables
- Design services around a single responsibility
- Use the providedIn: 'root' option for singleton servicesinject()
- Use the function instead of constructor injection`
Prompt:
> “How do Angular signals work?”
What Copilot does:
Calls search_documentation("signals") and returns official Angular documentation context.
---
Prompt:
> “Generate a service for user authentication”
What Copilot does:
Runs ng generate service user-auth through the MCP server — adds the file in the correct directory.
---
Prompt:
> “List all Angular modules in this project”
What Copilot does:
Uses list_projects and get_file_tree to find and display modules across the workspace.
---
Prompt:
> “What routes are defined in this app?”
What Copilot does:
Parses routing modules and shows route paths, guards, and lazy-loaded modules.
---
Prompt:
> “Convert this component to use the standalone API”
What Copilot does:
Updates component metadata with standalone: true, refactors imports, and removes old NgModule references.
---
Prompt:
> “Add Angular Material”
What Copilot does:
Triggers ng add @angular/material` to install the package and configure animations + theming.