npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@startinblox/boilerplate

v4.3.1

Published

Startin'blox Boilerplate

Readme

Startin'blox components repository boilerplate

Introduction

This repository provides a boilerplate for developing Startin'blox web components. It streamlines the creation and deployment of web components, whether used standalone or integrated within the Startin'blox ecosystem (Lit, Startin'blox Core, Store, Router, and Orbit). The primary objective is to enable developers to concentrate on web component logic by abstracting common complexities and providing essential functionalities out-of-the-box.

Features

This boilerplate includes:

  • Localization: Supports internationalization with platforms like Weblate, powered by @lit/localize.
  • Data Management: A comprehensive wrapper around the Startin'blox Store for simplified property handling (RDF or named).
  • Component Awareness: Mechanisms to manage race conditions and inheritance across external components.
  • Helper Utilities: Functions for data reactivity, filtering, and sorting.
  • Development Tools:
    • Storybook: For isolated component development and documentation, reducing the need for a heavy local environment.
    • Cypress: For component testing.
    • Unpluggin Icons: Access to a vast library of icons from Iconify.
    • Lit Integration: Pre-made component classes to accelerate development.
    • Vite-powered: Typescript, SASS, PostCSS and Autoprefixer, allowing you to focus on component logic rather than build configurations.
    • BiomeJS: Preconfigured for Startin'blox JS styling, using the most reasonable one, for linting and formatting. Integrate Biome with your preferred editor.

Quick Start for Developers

This section guides you through setting up the local development environment and using the boilerplate to create and test web components.

Local Development Setup

To get started with local development:

  1. Clone the repository:

    git clone https://git.startinblox.com/components/your-component-name.git
    cd your-component-name

    Note: If you are starting a new project from this boilerplate, refer to the "Developping new components from the boilerplate" section below.

  2. Install dependencies:

    npm install
  3. Run Storybook: Storybook is the primary development environment for isolated component development and documentation.

    npm run storybook

    This will open Storybook in your browser, typically at http://localhost:6006.

Using Your Components

For production usage, components can be served via a CDN like JSDelivr or self-hosted.

  <script type="module" src="https://cdn.jsdelivr.net/npm/@startinblox/core@latest/dist/store.js" defer=""></script>
  <!--
  Or the entire core:
  <script type="module" src="https://cdn.jsdelivr.net/npm/@startinblox/core@latest/dist/index.js" defer=""></script>
  -->
  <script type="module" src="https://cdn.jsdelivr.net/npm/your-component-name@latest" defer=""></script>
  <!-- ... -->
  <your-component-1 data-src="..."></your-component-1>
  <your-component-2>Hello World!</your-component-2>
  <!-- etc. -->

Developping new components from the boilerplate

Creating a New Component Repository

To initialize a new component repository from this boilerplate:

  1. Clone this repository:

    git clone https://git.startinblox.com/components/solid-boilerplate.git your-new-component-name
    cd your-new-component-name
  2. Rename the origin remote to upstream:

    git remote rename origin upstream
  3. Update project details: Modify the name, description, and repository.url fields in package.json to reflect your new component.

  4. Initial commit: Commit the changes with a major: Initial commit message.

  5. Create a new repository: Create a new repository on git.startinblox.com/components.

  6. Add the new repository as the origin remote:

    git remote add origin https://git.startinblox.com/components/your-component-name.git
  7. Configure Gitlab settings: Set up branch protection rules, enforce FF merge only, and configure cloning instead of fetching in your new repository's Gitlab settings.

  8. Push to origin master:

    git push -u origin master

Important Considerations

This boilerplate is designed as a library for multiple web components and intentionally does not include a default index.html file. Developers should use Storybook for isolated component development.

  • Avoid Blind Copy-Pasting: Do not simply copy files without understanding their purpose. This boilerplate includes specific configurations and integrations (e.g., Orbit, localization) that may not be relevant to all projects. Always review and adapt the code to your specific needs.
  • Understand Core Concepts: Familiarize yourself with the "Core Concepts" section to understand how data management, component awareness, and helper utilities are implemented.
  • Orbit Integration: The import @src/initializer; statement is only required if your component will be integrated with Startin'blox Orbit. If you are not using Orbit, you do not need this import.

Development Environment

Storybook is the primary development environment for isolated component development and documentation. Cypress is integrated for component testing.

For components intended to be packaged within the broader Startin'blox environment, integrating with a local Orbit instance is recommended.

Updating from the boilerplate

To keep your component repository synchronized with updates from this boilerplate:

  1. Ensure upstream is configured to point to this boilerplate's repository.

  2. Pull changes from the boilerplate's upstream:

    git pull upstream master
  3. Resolve any merge conflicts. Changes outside the boilerplate's core code should merge smoothly.

  4. Push the updates to origin master.

Core Concepts

Pre-made component classes

  • OrbitComponent: A component designed to display or handle a Resource or Container, optionally extending its functionality for Orbit integration.
  • ObjectsHandler: A component for rendering an array of objects, typically used within an OrbitComponent to display a Container.
  • ObjectHandler: A component for rendering a single object, commonly used within an OrbitComponent or ObjectsHandler to display a Resource.

Store reactivity

  • setupCacheInvalidation: Invalidates the store cache and updates the component when a save event occurs for resources listed by specified attributes and keywords.
  • setupOnResourceReady: Invalidates the store cache and updates the component upon a resourceReady event, independent of attributes.
  • setupOnSaveReset: Resets form values by calling the _setValue method (which must be custom-implemented) on a save event containing specified keywords.

Custom cache invalidation methods can be added:

async _afterAttach() {
  this._subscriptions.add(["name-of-the-event", (e) => {
    // Logic to execute when `name-of-the-event` occurs
  }]);
  // Ensure event deduplication before re-subscribing
  this._subscribe();
  // _afterAttach expects a Promise, you can reject on error
  return Promise.resolve();
}

OrbitComponent default attributes and methods

Attributes:

  • defaultDataSrc: (Optional) Used within Lit Tasks to track the original data source when the component's dataSrc is rewritten.
  • dataSrc: (Optional) Specifies the resource to display within a Lit Task.
  • nestedField: (Optional) Requires manual handling within a Lit Task.
  • uniq: (Optional) Allows multiple instances of the component within the same DOM.
  • route: (Optional) Enables router-awareness, preventing rendering/updating when the current route does not match expectations.
  • cherryPickedProperties: (Required) An array describing the expected RDF or named properties for the component.

Methods:

  • render: A Lit method; refer to Lit documentation. Should return a Lit Task or nothing.
  • _afterAttach: An asynchronous method called after the component is attached to the DOM and fully initialized. Expects a resolved or rejected Promise.
  • _navigate(e): Facilitates navigation using the router and predefined attributes within a render method.
  • _getProxyValue(dataSrc): An asynchronous method typically called within a Lit Task. It retrieves data based on cherryPickedProperties, is recursive by default, and allows cherryPickedProperties to be overridden.
  • _responseAdaptator(res): An asynchronous method called before _getProxyValue returns its result, allowing for response adaptation (e.g., prefixing a name property based on type).
  • gatekeeper: A pre-written method for components intended to operate exclusively within Orbit, simplifying gatekeeping logic.

OrbitComponent inherits methods from ObjectsHandler.

ObjectsHandler methods

  • hasType(type): Checks if any object within this.objects shares the requested type, returning a boolean.

ObjectHandler methods

  • isType(type): Checks if the object shares the requested type, returning a boolean.

Available helpers

The src/helpers directory contains various utilities:

  • datas:
    • dataBuilder: For creating mock data.
    • filterGenerator: For seamless object filtering using filterObjectByX methods.
    • sort: A general-purpose sorting method.
  • ui:
    • formatDate: For date formatting using native Intl methods.
    • lipsum: For configuring mock word, sentence, or paragraph generation.
  • utils:
    • requestNavigation: A wrapper around the Startin'blox Router for JavaScript-based navigation.
    • uniq: A unique ID generator.

cherryPickedProperties explained

The cherryPickedProperties array within an OrbitComponent defines the properties expected by the component. Each entry can have up to four attributes:

  • key: The original property name or RDF.
  • value: The name this property will have within the component.
  • cast: A callback function (e.g., formatDate helper) to transform the property's value.
  • expand: If true, and the property contains a Resource or Container, it will be recursively expanded using the same cherryPickedProperties. Exercise caution with circular dependencies; _responseAdaptator is often more suitable for such cases, allowing _getProxyValue to be called with recursive=False or different cherryPickedProperties. Defaults to false.

Example:

  cherryPickedProperties: PropertiesPicker[] = [
    { key: "name", value: "name" },
    // Using the project property two times: One with a cast to keep its @id, and one expanded giving complete access to its datas
    { key: "project", value: "projectId", cast: (r) => r["@id"] },
    // This will expand the `project` property, using the same cherryPickedProperties, so it'll contain any `project.name`, `project.project` and `project.description`
    { key: "project", value: "project", expand: true },
    { key: "description", value: "description" },
    // In any case, the `_originalResource`, the `@id`, `@context` and `@type` will be fetched and accessible
  ];

Development workflow

Localization

This project utilizes @lit/localize for internationalization.

  1. Configure lit-localize.json, specifically the targetLocales key.
  2. Run npm run locale:extract to generate initial localization files.
  3. Execute npm run locale:extract to update localization files whenever str or msg methods from Lit Localize are used. XLIFF files will be generated in the locales directory.
  4. Before production deployment, run npm run locale:build to generate built localization files.

To change the locale at runtime within an application:

// With Orbit:
window.setLocale.map((setLocale) => setLocale("your-lang-code"));
// Without Orbit:
window.setLocale("your-lang-code");

To retrieve the current locale:

// With Orbit:
window.getLocale.map((locale) => console.log(locale));
// Without Orbit:
console.log(window.getLocale("your-lang-code"));

Testing

# Run all tests
npm run cy:run
# Open Cypress's interface
npm run cy:open

Building for production

# Generate localization files
npm run locale:build
# Generate Storybook documentation
npm run build-storybook
# Build the component repository
npm run build

Orbit Integration

Components built with this boilerplate are designed to work seamlessly with Orbit without requiring specific configurations.

  • Initializer: To prevent potential race conditions when integrating with Orbit, include import @src/initializer; at the top of your component's file, before the @customElement declaration. This import is only necessary if your component will be used within an Orbit environment.
  • Performance Optimization: Application performance can be optimized by utilizing the gatekeeper method within your OrbitComponent's render methods.
  • Limitations without Orbit: Without a complete Orbit environment, interactions with external components (e.g., route management, component deduplication, global localization, conditional component display) may be limited.

Best practices

Adhere to general web component usage rules, as outlined by MDN Web Docs or the webcomponents.org guideline.

Tailor web components to their expected application environment. Features like the gatekeeper and localization usage should be standard practice, not exceptions. This approach ensures components are efficient and integrate effectively with the broader application and other components.

License

MIT