Developing a Web Components Library with Lit

Different product sections live by their own rules — the interface diverges, and each enhancement drags edits in several places. We develop a turnkey Web Components library with Lit: unified elements, documentation, and handover to the team. We reduce time to assemble new screens and eliminate discrepancies between sections.

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Frequently Asked Questions

Why a Web Components library degrades as a product grows

The first version of a Web Components library usually looks convincing: a button, an input field, a dropdown list, a modal window — each element in a single instance, with described states and predictable behavior.

The problem comes not from the code but from the process: the next product section makes its own button because "it needs to be urgent and slightly different," the third takes the second and adds a special case to it. By release, the same entity exists in three implementations in the project.

Then combinatorics kicks in.

Five sections and twenty elements produce not twenty components but dozens of behavior variants: one button has a loading state, another doesn't; focus handling is implemented in one place and lost in another; spacing comes from three different style sets.

Discrepancies between sections accumulate quietly — they aren't visible in a demo, they surface in production in specific scenarios.

The cost shows up in supporting the product interface. Any fix stops being a single task: you need to find all copies, assess which ones will react to the change, and not break a section that lives by its own rules.

Recurring layout defects return after every release — the symptom is fixed on a specific page, not the source. Tests are duplicated across sections: coverage grows, but confidence in the product's behavior doesn't.

Unified interface components remove this not by agreement but by architecture. An element, its states, and styles are described in one place; sections connect it as a dependency and cannot silently override behavior, and a change reaches all consumers at once.

Below we examine how such a Web Components library is structured and what steps to take to close discrepancies between sections as the product scales.

What changes after migrating the interface to unified components

A unified set of elements changes not the appearance of the interface but the cost of changing it.

As long as each screen has its own buttons, tables, and forms, any fix multiplies across the codebase: validation, loading states, and error handling have to be repeated in every section, and the same defects surface again.

Options that are actually chosen between before starting:

Option When it fits Limitations
Custom code for each screen one interface, short lifespan, one team the fix is made separately in every place, defects repeat
Ready-made element library a standard interface without custom design requirements hard to adapt to brand style, extra code in the build
In-house Web Components library on Lit multiple products or teams and a shared design requires a stage for designing the component set, documentation, and versioning

After the transition, a typical screen is assembled from ready-made blocks, so the release time for a new section is reduced severalfold, not by percentages.

The share of recurring defects falls: a fix inside a component closes the problem across all products at once, and an entire class of failures goes away — discrepancies in validation, different button states, layout that has drifted apart on neighboring pages.

Maintenance effort shifts from copying fixes to changing one implementation, and a visual style change becomes a task for one module rather than a series of coordinated updates across all teams.

Component library delivery options: comparing modes

A component library is rarely commissioned "from scratch": there is usually already a working interface, an adopted design system, or someone else's element set that needs to be integrated into your environment.

The choice comes down to four delivery modes — they differ not in quality but in who is responsible going forward for markup, behavior, and version compatibility.

Option When it fits Limitations of the approach
In-house component library (for example, on Lit) The product evolves over years, needs a unified visual language and a predictable update pace Requires versioning and backward-compatibility rules; the first release comes later than with wrappers
Wrappers over a ready-made system The design system is already adopted in the company, deadlines are tight, the ready-made set covers most screens We inherit someone else's decisions and release pace: a major version of the external system breaks the wrappers
Custom set of elements A narrow scenario with heavy logic — an editor, an interactive map, a complex form Higher maintenance cost per component, reuse outside the project is almost zero
Gradual replacement of scattered elements There is a legacy interface that cannot be stopped for a rewrite Two markup and style systems live side by side for a long time, an explicit compatibility boundary is needed

We discuss the limitations of each mode before starting: what we consider the component's public interface, how we mark deprecated things, and by what sign we understand that it's time to replace a wrapper with our own.

This is the selection criterion — not how "trendy" the approach is, but how many fixes it can withstand by the second or third release.

Implementation stages: from interface audit to handover to the team

The order of stages is not accidental: until a complete list of elements is collected, the library schema will be guesswork. Inventory provides priorities — what to migrate first and what to leave on the pages.

  1. Interface audit. We collect recurring elements across all pages: buttons, fields, lists, tables, modal windows. The list with usage frequency and duplicate list sets the work queue.
  2. Library schema. We arrange elements by levels — base, composite, domain-specific — and fix dependencies so a simple element doesn't pull a complex one along.
  3. Naming rules. A common prefix in the tag name, hyphens instead of spaces, unified property and event names. We enforce the rules in automated code checks: a violation is visible at build time, not during review.
  4. Implementation on Lit. Reactive properties, isolated styles, and design values come from theme tokens. One element — one file and one set of attributes; it can be updated and rolled back pointwise.
  5. Accessibility check. For each element we fix the role, keyboard operation, focus order, and contrast. Automated runs are part of the build; we manually check key scenarios with a screen reader.
  6. Documentation. A showcase with live examples, a page per element, a changelog, and version update rules — one source instead of chat correspondence.
  7. Handover to the team. Code walkthrough, the cycle for adding a new element, areas of responsibility. The team adds the first element itself; we check the result.

After that, the library evolves without us: an element is added by template, and changes go through the same checks.

What remains in the repository and documentation after project delivery

We hand over not a "folder with code" but a working repository that a new engineer can understand without accompanying explanations.

Below is what exactly remains with you after delivery of the Lit component library: you can evolve it in-house or hand it to another team without losing context.

  • Sources and build. A monorepo with component packages, build configuration, and code checking rules; the build is reproduced with one command on a clean machine.
  • Versioning rules. Semantic package versions and a changelog by type — breaking, new features, fixes; the consumer can see which update is safe to install.
  • Component documentation. For each element: purpose, properties and events, slots, markup examples, accessibility notes — all in a shared catalog.
  • Usage examples. Demo stands for typical scenarios — a form, a table, a design theme; they run locally and serve as a basis for your pages.
  • Update policy. The version release procedure: checks, build, publication to a private registry, notification of consumer teams, and separately — rollback to the previous version.
  • Access roles. Separation of permissions for the repository, package registry, and documentation catalog: who merges changes into the main branch, who publishes versions.
  • Project artifacts. An architecture diagram, a decision log for contentious points, and an acceptance checklist — so that in six months the logic isn't reconstructed from chat correspondence.

The handover concludes with a walkthrough with your team: we go through the repository, demonstrate a version release, and answer questions about how the components are structured.

Case study: how discrepancies between sections of one product were eliminated

The product grew by sections: the catalog, personal account, checkout, and support section were built by different teams at different times. Each started from its own markup, so the same button, input field, and filter table existed in seven independent variants.

Visually they almost matched, but behaviorally they didn't: in one place the button blocked repeated clicks, in another it sent the request twice, in another it didn't show a loading state.

What was changed

The interface elements were moved into a single Web Components library on Lit — a unified source of elements for all sections. Each element now has one source, a version, and described states, while sections stopped keeping their own copies and connect the shared set.

For the mobile scenario, a compact variant was deliberately left — it differs only in spacing density, with shared behavior.

Metrics before and after

Before: seven variants of one element and a fix release time of four to six days — the change went through all sections in turn, each with its own check.

After: one source plus one deliberate mobile variant, the fix is shipped the same day and arrives in all sections simultaneously; the check set was reduced from five to one.

An entire class of failures went away — behavioral divergence between sections. Going forward, product support comes from a single source: a new section connects ready-made elements instead of designing them anew and again accumulating deviations.

How a design system differs from a ready-made element set

A ready-made element set answers the question "what does the button look like?" A design system answers another: "why is it like that, and what will change if one value in the tokens is adjusted?" This is a difference in responsibility boundaries, not in the number of files in the delivery.

A set usually includes screen mockups or individual interface fragments.

A design system includes the token layer (color, typography, spacing, states), the components themselves as Web Components, rules for their composition, package versioning, automated tests, and documentation for the public interface of each element.

The division of roles here is strict. The designer owns the visual language and changes token values; the engineer is responsible for implementation, accessibility, and backward compatibility. Contentious cases are resolved at the token level, not by editing markup on a specific screen.

The practical difference is visible on the very first redesign. An element set has to be edited page by page: the more screens, the higher the risk of discrepancies and lost states.

Changing a token in the design system propagates across all components at once, and tests show which places reacted. We build libraries of this level on Lit — the components remain lightweight and integrate into existing pages without a rewrite.

The result: in the delivery you get not pictures but a working artifact — a component package, tokens, rules, and documentation that live in the repository and are updated together with the product.

Technical concerns: compatibility, accessibility, updates

Integrating the library raises four objections: compatibility with the old interface, accessibility, update procedure, and migration without stopping the site. We break them down by mechanics — at the level of adopted decisions, not promises.

The basic principle: components on Lit are native browser tags. They coexist with the previous markup and are connected block by block, rather than by replacing the entire interface at once.

Will the library coexist with old sections?

A component is a regular tag with isolated styles: it fits into any page alongside the old markup, and the template engine keeps working. We migrate block by block — filters and forms first. Fallback implementations are needed only where the browser doesn't support the built-in mechanisms.

How is keyboard navigation and interface accessibility handled?

For the component, we define the focus traversal order, a visible outline, Enter and arrow key behavior, and the absence of traps in modal windows. Dynamic blocks announce changes to the screen reader.

We check accessibility at the component level, not the finished page — a fix doesn't turn into a section rework.

In what order are library updates released?

We release fixes and behavior changes separately, warn about incompatible changes in advance, and keep the old call working until an agreed deadline. Each release includes a changelog and migration instructions.

Can we migrate without stopping the site?

The migration follows a route: the new section is enabled for part of the traffic, the old one remains available, and we compare behavior on live sessions. Switching is a route flag, so rollback returns the previous variant without a new build.

Let's discuss the task and come back with an estimate and work plan

To discuss the task substantively, we need context: what interfaces already exist, where common elements are duplicated, and whether there are Web Components developments that need to be preserved or migrated.

During the review, we look at the application structure, platform constraints, and how the library will connect to your environment. The outcome of the meeting is not a presentation but a document that can be used to start work.

  • Review of current interfaces: which elements repeat across products and what is truly worth moving into a shared library, and what should stay in place.
  • Scope of work: stages, roles on both sides, dependencies, and points where your team's decisions are needed, not ours.
  • Target library schema: package composition, versioning rules, style isolation, and design theme support.
  • Handover procedure: how components, documentation, and update rules pass to your developers and who is responsible for acceptance.
  • Rollout plan to products: a pilot on one application, readiness criteria, and the order for connecting the rest.
  • Estimate and work plan: timelines by stage and the conditions under which they are revised.
  • Project start: what we need from you in the first week — access, repositories, responsible people, and a communication channel.

Describe the task — how many products, which platforms, what has already been done in-house. We'll come back with an estimate and work plan, and also suggest a time to review the details.

Our competencies:

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1393
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1368
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1139
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1152
  • Website development for SBH Partners
    Website development for SBH Partners
    1231
  • Website development for Red Pear
    Website development for Red Pear
    641