What Is the readPatterns Function in Impeccable? Parsing DO/DON'T Design Patterns
The readPatterns function parses the frontend-design/SKILL.md markdown file to extract structured DO and DON'T design guidelines, returning a JSON object that powers the Patterns and Anti-Patterns tabs in the Impeccable web interface.
The readPatterns function in the pbakaus/impeccable repository serves as the data bridge between human-written markdown guidelines and machine-readable API responses. Located in scripts/lib/utils.js, this utility transforms static design rules documented in the skill file into dynamic content for the application's frontend. By programmatically extracting checklist items marked with **DO**: and **DON'T**: prefixes, Impeccable maintains a single source of truth for frontend design standards.
What Does readPatterns Do?
The readPatterns function is a markdown parser utility that reads source/skills/frontend-design/SKILL.md and isolates design guidelines organized under category headings (e.g., Typography, Color & Contrast). It categorizes items based on whether they follow the **DO**: or **DON'T**: convention used throughout the skill documentation.
Returned Data Structure
The function returns an object containing two parallel arrays:
{
"patterns": [
{ "name": "Typography", "items": ["Use a maximum of two font families", "..."] },
{ "name": "Color & Contrast", "items": ["Maintain a contrast ratio of at least 4.5:1", "..."] }
],
"antipatterns": [
{ "name": "Typography", "items": ["Use more than two font families", "..."] },
{ "name": "Color & Contrast", "items": ["Rely solely on color to convey information", "..."] }
]
}
This structure separates positive recommendations (patterns) from prohibitions (antipatterns), preserving the section order defined in the original markdown.
How readPatterns Parses DO and DON'T Items
As implemented in scripts/lib/utils.js (lines 92-162), the function follows a deterministic line-by-line scanning algorithm:
-
File Resolution: The function constructs the absolute path to
source/skills/frontend-design/SKILL.mdusingpath.join(rootDir, 'source/skills/frontend-design/SKILL.md')(lines 97-99). -
Line Tokenization: It reads the file with
fs.readFileSync(..., 'utf-8')and splits the content into an array of lines usingcontent.split('\n')(lines 104-106). -
Heading Detection: The parser tracks the current category by detecting lines starting with
###(markdown H3 headings). When found, it strips the prefix and stores the section name (lines 114-119). -
DO Pattern Extraction: Lines beginning with
**DO**:have their prefix removed and the remaining text appended to thepatternsMapunder the current section key (lines 124-130). -
DON'T Pattern Extraction: Similarly, lines starting with
**DON'T**:are cleaned and pushed to theantipatternsMapfor the active section (lines 134-140). -
Array Conversion: After scanning completes, the function converts the internal maps into ordered arrays based on
sectionOrder, ensuring the UI receives categories in a consistent sequence (lines 146-158). -
Return Value: Finally, it returns the structured object containing
patternsandantipatternsarrays (lines 160-162).
Where readPatterns Is Used in the Impeccable Architecture
The function operates as the backend data source for the application's design guidelines API.
The API Handler Layer
In server/lib/api-handlers.js (lines 33-38), the getPatterns function acts as a thin wrapper that calls readPatterns(PROJECT_ROOT) and returns the result. This abstraction allows the API layer to remain agnostic of the file parsing implementation.
The Web Server Route
The main server entry point in server/index.js (lines 86-92) registers the /api/patterns endpoint. When a client requests this route, the server invokes getPatterns() and serves the JSON payload directly to the frontend.
The Frontend Consumer
The client-side application in public/app.js fetches from /api/patterns to populate the "Patterns" and "Anti-Patterns" tabs. By consuming this API instead of hardcoding guidelines, the UI automatically reflects any updates to source/skills/frontend-design/SKILL.md after a server restart.
Code Examples: Working with readPatterns
Direct Usage in Node.js or Bun
You can import and execute readPatterns directly in scripts to access the design guidelines programmatically:
import { readPatterns } from './scripts/lib/utils.js';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const ROOT = join(__dirname, '..');
const { patterns, antipatterns } = readPatterns(ROOT);
console.log('Design DOs:');
patterns.forEach(section => {
console.log(`\n${section.name}:`);
section.items.forEach(item => console.log(` ✓ ${item}`));
});
console.log('\nDesign DON\'Ts:');
antipatterns.forEach(section => {
console.log(`\n${section.name}:`);
section.items.forEach(item => console.log(` ✗ ${item}`));
});
Consuming the JSON API
For browser-based applications or external tools, consume the exposed endpoint:
async function renderDesignGuidelines() {
const response = await fetch('/api/patterns');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const { patterns, antipatterns } = await response.json();
// Render patterns tab
const patternsContainer = document.getElementById('patterns');
patterns.forEach(section => {
const details = document.createElement('details');
details.innerHTML = `
<summary>${section.name}</summary>
<ul>${section.items.map(i => `<li>${i}</li>`).join('')}</ul>
`;
patternsContainer.appendChild(details);
});
}
Summary
- The
readPatternsfunction inscripts/lib/utils.jsparsessource/skills/frontend-design/SKILL.mdto extract structured design guidelines. - It identifies DO items as patterns and DON'T items as antipatterns, grouping them by markdown H3 headings.
- The function returns a JSON object with
patternsandantipatternsarrays, each containing section names and checklist items. - It serves as the data foundation for the
/api/patternsendpoint, enabling dynamic rendering of design guidelines without hardcoded content. - Changes to the markdown source automatically propagate to the API output, ensuring the single source of truth remains synchronized.
Frequently Asked Questions
What file format does readPatterns expect?
The readPatterns function expects a markdown file located at source/skills/frontend-design/SKILL.md relative to the provided root directory. Specifically, it parses H3 headings (### Category Name) as section delimiters and looks for list items prefixed with **DO**: or **DON'T**: to populate the patterns and antipatterns arrays.
How does readPatterns handle section ordering?
According to the implementation in scripts/lib/utils.js (lines 146-158), the function maintains section order using a predefined sectionOrder array. After parsing the markdown into temporary maps, it iterates through this ordered list to construct the final arrays, ensuring the API returns categories in a consistent, predictable sequence regardless of their physical order in the file.
Can readPatterns be used outside of the Impeccable server?
Yes. While readPatterns is primarily consumed by the API handlers in server/lib/api-handlers.js, it is exported as a standalone utility from scripts/lib/utils.js. You can import it into build scripts, documentation generators, or testing frameworks to access the design guidelines programmatically without starting the web server, as demonstrated in the Node.js usage example above.
What is the difference between patterns and antipatterns in the return value?
The patterns array contains items marked with **DO**:, representing recommended frontend design practices, while the antipatterns array contains items marked with **DON'T**:, representing practices to avoid. Both arrays share the same section structure—objects with name and items properties—but are kept separate to support the tabbed UI interface in the Impeccable application.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →