Building reusable UI components is a challenging endeavor. For any given component, there are many details to consider. Having a standard component spec template for your team can be a huge help in delivering high quality, consistent, and accessible components.
When I was at Microsoft, I helped design the spec template used by FAST and Fluent UI Web Components. I also contributed many of those ideas into the W3C Open UI official spec template. I’d like to share the key elements of those templates with you in this post in the hopes that it can be of service to you and your team.
Not just when writing a component spec, but really when writing any technical or strategy document, it’s good to start with an overview or “executive summary”. For a component spec, the overview should minimally provide the component’s name along with a brief description.
Beyond this, I’ve found several sub-sections are generally needed to help provide context and set a clear direction:
- Background — Provide some relevant historical context, including listing any existing product or organizational issues.
- Use Cases — Describe the purpose of the component and its primary uses. It’s valuable to link these to customer feedback, product requests, and industry patterns.
- Features — A list of the key features of the component can help set the scope of the work.
- Non-goals — It can be just as important to list non-goals as it is to list use cases and features. This can help make explicit what will not be part of the component. For example, you may spec out a data grid component but explicitly exclude any features for data loading. Between the use-cases, features, and non-goal sections, you want to make it very clear what your MVP is.
- Risks and Challenges — There is some risk in every software development task. Take time to think through any risks associated with implementing this specific component. This should include listing out any breaking changes that may be needed in other parts of the system, or any dependency updates that are required.
- Prior Art/Examples — Don’t assume you are the first one to ever build a component like this. Take time to research what has been done before and provide links and screenshots to existing, canonical, or exemplary implementations or designs.
The design section of the spec should focus in on thinking through several different perspectives:
- A customer using the component in a site/app.
- A designer customizing the component for a specific context.
A few critical subsections are:
Take some time to think through the details of the public API surface of the component. Elements to include are:
- Component Name
- Properties and Attributes
Consider both high and low-level APIs. If you are building a re-usable component, the goal is to design something powerful and extensible at the low-level with a high-level API that is ergonomic and simple to use for both designers and developers. Consider whether any aspects of the component can/should be pluggable: how will you support tree-shaking and prevent component bloat?
Outline the semantic structure of the component with a diagram of its visual tree (Shadow DOM for Web Components). List out the key areas of customization including:
- Slot Names
- CSS Parts
- Slotted Content Restrictions
- Host and Slotted Classes
This work should be done in close collaboration with a visual design partner so that both the API and Anatomy are designed along-side the Visual Appearance.
Provide Figma files and other design assets. Be sure to account for the various component states, including hover, active, disabled, etc. as well as validity, and appearance variants. Make sure the design is consistent with the design language as-a-whole and uses the correct design tokens. Any variations should be “earned” and justified with strong reasoning. Design and engineering should work closely to co-develop the visual appearance along-side the API and Anatomy.
In the implementation section of the spec, you’ll want to detail a few technical considerations, such as relevant web standards and integration scenarios. Here are a few things to think though:
- States — What are the key states that the component can be in and how do the state transitions work? What is the relationship between human interactions and state transitions?
- Accessibility — How does keyboard navigation and focus work? Does the component support form integration and how? How is the component used with assistive technology? What role(s) and ARIA attributes are important?
- Globalization — Does the component need special RTL handling? If it uses icons or special fonts, can they be swapped out? Does the component require localization of text?
- Security — Are there any security implications for the component? This could be the component as a whole or various internal technical approaches.
- Performance — Are there any performance pitfalls or challenges that need to be kept in mind? Are there different approaches to the implementation with different performance characteristics?
- Dependencies — Will the implementation be dependent on any 3rd party libraries, polyfills, or internal libraries/utilities/tools? Are these new or existing dependencies for the project? What is their health/stability?
- Test Plan — What is the plan for testing the component? Are there any unique challenges/needs in this area?
- Tooling — Does the component have tooling implications such as needing to update or change tools? What is the plan for supporting the component with already in-use design/dev tools?
- Documentation — Does the component have any unique documentation requirements? What examples/demos will be made to showcase proper use of the component? Does the complexity of the component warrant any additional in-depth architectural or engineering docs or diagrams?
In addition to the information above, I’ve found that an appendix can be advantageous. Here are a couple of common subsections:
- Resources — A list of any related resources such as web standards, discussion threads, diagrams, tutorials, etc.
- Next Steps — What next steps, if any, are there? Is there some functionality that would be a nice-to-have or is a common feature in other implementations that could be added but is not considered part of the MVP? Does adding this component increase technical debt that will need to be paid down later? Does its addition imply a need to refactor other components or core infrastructure in the future?
Beyond simply writing specs, it’s good to have at least a light process around them. The process should have a tight, iterative and collaborative feedback loop. What you don’t want is to send an engineer off to write the entire spec behind closed doors, only to come back much later with something that has significant issues. This causes both waste and frustration.
One pattern I’ve used in the past is to have phases associated with reviews. Here is an example three-phase process you could use:
Complete the “Overview” section of the spec only. Before moving on, briefly review this part of the spec with relevant stakeholders to make sure you are heading in the right direction. The review can be handled asynchronously, entirely through PR or doc comments. But if needed, it can be done via a short, highly focused face-face meeting. Whatever you do, keep it light. All you need is confirmation that you’re on the right track at this point.
TIP: Whenever you run a face-to-face meeting, be sure to send a link to the relevant documents ahead of time so folks can read them in advance and be prepared to discuss. Your meeting invite should be clear about the prerequisite of reading beforehand and the goals of the meeting. If you can’t provide the document ahead of time, then allot time at the beginning of the meeting for attendees to read the doc before discussion begins. It’s imperative that everyone starts with the proper background and context.
Collaborate with your design partner on the “Design” and “Implementation” parts of the spec. You may want to spike out a few technical details and the designer will want to complete the initial design work. It’s good to time-box this section, particularly if technical spikes are involved. Once these sections are complete, along with the design work, again provide opportunities for stakeholders to review. It’s important to do this before you get heavily invested into an implementation. Parallel to this the design partner should be going through design reviews with their peers/stakeholders as well.
TIP: When doing technical spikes, do only as much as you need to answer the pressing questions you have. Enforce a strict timebox and be prepared to throw out your spikes before you begin the real implementation.
Avoid getting attached.
Once all spec feedback is addressed, move on to the actual implementation. I recommend starting this process by immediately creating a work-in-progress pull request so that the technical work has visibility and any relevant code owners or leads can review as you go along. It’s much easier for a lead if they are in the loop from the beginning, rather than having to deal with a massive PR at the end. Think through how you can phase the development out as smaller commits and PRs rather than a large chunk of work. Reach out to peers all along the way to check in. Avoid going behind closed doors and coming out when it’s all done. You want the benefit of feedback as you go.
Once the work is done and all pull request reviews and feedback have been addressed, it’s time to merge. Make sure your pull request is accompanied by documentation. If you’ve got a spec as described above, that can easily be morphed into living documentation for the component. Consider also following up with your team or organization to showcase the new component and share technical learnings with others.
IMPORTANT: I don’t intend for the phases above to imply anything formal like “sprints”. The entire process could be executed in a few days, multiple times within a single sprint. It could also span across sprints. It fits easily within a Kanban approach as well. The main idea is to have a well-known, light way to help you get from point A to point B successfully. You want to have guardrails in place, so you don’t go off track, spin your wheels, or cause a huge “pile up” at the end of the process.
I hope this post can provide a template for you when you have to build your next component, or at least a checklist reference to help you think through the many aspects of the task. I encourage you to customize the template and the process to your team, product, and organization’s culture, so you can find the right combination that helps you deliver quality to your customers within your operational constraints.
If you enjoyed this look into real-world component spec templates and processes, you might want to check out my Web Component Engineering course. I’d also love it if you would subscribe to this blog, subscribe to my YouTube channel, or follow me on twitter. Your support greatly helps me continue writing and bringing this kind of content to the broader community. Thank you!