dembrandt 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,403 +4,101 @@
4
4
  [![npm downloads](https://img.shields.io/npm/dm/dembrandt.svg)](https://www.npmjs.com/package/dembrandt)
5
5
  [![license](https://img.shields.io/npm/l/dembrandt.svg)](https://github.com/thevangelist/dembrandt/blob/main/LICENSE)
6
6
 
7
- A CLI tool for extracting design tokens and brand assets from any website. Powered by Playwright with advanced bot detection avoidance.
7
+ Extract any website’s design system into design tokens in a few seconds: logo, colors, typography, borders, and more. One command.
8
8
 
9
9
  ![Dembrandt Demo](showcase.png)
10
10
 
11
- ## Quick Start
11
+ ## Install
12
12
 
13
13
  ```bash
14
- npx dembrandt stripe.com
14
+ npx dembrandt bmw.de
15
15
  ```
16
16
 
17
- No installation required! Extract design tokens from any website in seconds. Or install globally with `npm install -g dembrandt`.
17
+ Or install globally: `npm install -g dembrandt` then run `dembrandt bmw.de`
18
18
 
19
- ## What It Does
19
+ Requires Node.js 18+
20
20
 
21
- Dembrandt analyzes live websites and extracts their complete design system:
21
+ ## What to expect from extraction?
22
22
 
23
- - **Logo** Logo detection (img/svg) with dimensions and source URL
24
- - **Favicons** All favicon variants with sizes and types
25
- - **Colors** — Semantic colors, color palette with confidence scoring, CSS variables (both hex and RGB formats)
26
- - **Typography** — Font families, sizes, weights, line heights, font sources (Google Fonts, Adobe Fonts, custom)
27
- - **Spacing** — Margin and padding scales with grid system detection (4px/8px/custom)
28
- - **Border Radius** Corner radius patterns with usage frequency
29
- - **Shadows** — Box shadow values for elevation systems
30
- - **Buttons** Component styles with variants and states
31
- - **Inputs** — Form field styles (input, textarea, select)
32
- - **Links** — Link styles with hover states and decorations
33
- - **Breakpoints** — Responsive design breakpoints from media queries
34
- - **Icons** — Icon system detection (Font Awesome, Material Icons, SVG)
35
- - **Frameworks** — CSS framework detection (Tailwind, Bootstrap, Material-UI, Chakra)
36
-
37
- Perfect for competitive analysis, brand audits, or rebuilding a brand when you don't have design guidelines.
38
-
39
- ## Why It Matters
40
-
41
- **Designers** — Analyze competitor systems, document production tokens, audit brand consistency
42
-
43
- **Developers** — Migrate design tokens, reverse engineer components, validate implementations
44
-
45
- **Product Managers** — Track competitor evolution, quantify design debt, evaluate vendors
46
-
47
- **Marketing** — Audit competitor brands, plan rebrands, monitor brand compliance
48
-
49
- **Engineering Leaders** — Measure technical debt, plan migrations, assess acquisition targets
50
-
51
- ## How It Works
52
-
53
- Uses Playwright to render the page, extracts computed styles from the DOM, analyzes color usage and confidence, groups similar typography, detects spacing patterns, and returns actionable design tokens.
54
-
55
- ### Extraction Process
56
-
57
- 1. **Browser Launch** - Launches Chromium with stealth configuration
58
- 2. **Anti-Detection** - Injects scripts to bypass bot detection
59
- 3. **Navigation** - Navigates to target URL with retry logic
60
- 4. **Hydration** - Waits for SPAs to fully load (8s initial + 4s stabilization)
61
- 5. **Content Validation** - Verifies page content is substantial (>500 chars)
62
- 6. **Parallel Extraction** - Runs all extractors concurrently for speed
63
- 7. **Analysis** - Analyzes computed styles, DOM structure, and CSS variables
64
- 8. **Scoring** - Assigns confidence scores based on context and usage
65
-
66
- ### Color Confidence
67
-
68
- - **High** — Logo, brand elements, primary buttons
69
- - **Medium** — Interactive elements, icons, navigation
70
- - **Low** — Generic UI components (filtered from display)
71
-
72
- Only shows high and medium confidence colors in terminal. Full palette in JSON.
73
-
74
- ### Typography Detection
75
-
76
- Samples all heading levels (h1-h6), body text, buttons, links. Groups by font family, size, and weight. Detects Google Fonts, Adobe Fonts, custom @font-face.
77
-
78
- ### Framework Detection
79
-
80
- Recognizes Tailwind CSS, Bootstrap, Material-UI, and others by class patterns and CDN links.
81
-
82
- ## Installation
83
-
84
- ### Using npx (Recommended)
85
-
86
- No installation needed! Run directly with `npx`:
87
-
88
- ```bash
89
- npx dembrandt stripe.com
90
- ```
91
-
92
- The first run will automatically install Chromium (~170MB).
93
-
94
- ### Global Installation
95
-
96
- Install globally for repeated use:
97
-
98
- ```bash
99
- npm install -g dembrandt
100
- dembrandt stripe.com
101
- ```
102
-
103
- ### Prerequisites
104
-
105
- - Node.js 18 or higher
106
-
107
- ### Development Setup
108
-
109
- For contributors who want to work on dembrandt:
110
-
111
- ```bash
112
- git clone https://github.com/thevangelist/dembrandt.git
113
- cd dembrandt
114
- npm install
115
- npm link
116
- ```
23
+ - Colors (semantic, palette, CSS variables)
24
+ - Typography (fonts, sizes, weights, sources)
25
+ - Spacing (margin/padding scales)
26
+ - Borders (radius, widths, styles, colors)
27
+ - Shadows
28
+ - Components (buttons, inputs, links)
29
+ - Breakpoints
30
+ - Icons & frameworks
117
31
 
118
32
  ## Usage
119
33
 
120
- ### Basic Usage
121
-
122
- ```bash
123
- # Using npx (no installation)
124
- npx dembrandt <url>
125
-
126
- # Or if installed globally
127
- dembrandt <url>
128
-
129
- # Examples
130
- dembrandt stripe.com
131
- dembrandt https://github.com
132
- dembrandt tailwindcss.com
133
- ```
134
-
135
- ### Options
136
-
137
- **`--json-only`** - Output raw JSON to stdout instead of formatted terminal display
138
-
139
- ```bash
140
- dembrandt stripe.com --json-only > tokens.json
141
- ```
142
-
143
- Note: JSON is automatically saved to `output/domain.com/` regardless of this flag.
144
-
145
- **`-d, --debug`** - Run with visible browser and detailed logs
146
-
147
- ```bash
148
- dembrandt stripe.com --debug
149
- ```
150
-
151
- Useful for troubleshooting bot detection, timeouts, or extraction issues.
152
-
153
- **`--verbose-colors`** - Show medium and low confidence colors in terminal output
154
-
155
- ```bash
156
- dembrandt stripe.com --verbose-colors
157
- ```
158
-
159
- By default, only high-confidence colors are shown. Use this flag to see all detected colors.
160
-
161
- **`--dark-mode`** - Extract colors from dark mode
162
-
163
- ```bash
164
- dembrandt stripe.com --dark-mode
165
- ```
166
-
167
- Enables dark mode preference detection for sites that support it.
168
-
169
- **`--mobile`** - Extract from mobile viewport
170
-
171
- ```bash
172
- dembrandt stripe.com --mobile
173
- ```
174
-
175
- Simulates a mobile device viewport for responsive design token extraction.
176
-
177
- ## Output
178
-
179
- ### Automatic JSON Saves
180
-
181
- Every extraction is automatically saved to `output/domain.com/YYYY-MM-DDTHH-MM-SS.json` with:
182
-
183
- - Complete design token data
184
- - Timestamped for version tracking
185
- - Organized by domain
186
-
187
- Example: `output/stripe.com/2025-11-22T14-30-45.json`
188
-
189
- ### Terminal Output
190
-
191
- Clean, formatted tables showing:
192
-
193
- - Color palette with confidence ratings (with visual swatches)
194
- - CSS variables with color previews
195
- - Typography hierarchy with context
196
- - Spacing scale (4px/8px grid detection)
197
- - Shadow system
198
- - Button variants
199
- - Component style breakdowns
200
- - Framework and icon system detection
201
-
202
- ### JSON Output Format
203
-
204
- Complete extraction data for programmatic use:
205
-
206
- ```json
207
- {
208
- "url": "https://example.com",
209
- "extractedAt": "2025-11-22T...",
210
- "logo": { "source": "img", "url": "...", "width": 120, "height": 40 },
211
- "colors": {
212
- "semantic": { "primary": "#3b82f6", ... },
213
- "palette": [{ "color": "#3b82f6", "confidence": "high", "count": 45, "sources": [...] }],
214
- "cssVariables": { "--color-primary": "#3b82f6", ... }
215
- },
216
- "typography": {
217
- "styles": [{ "fontFamily": "Inter", "fontSize": "16px", "fontWeight": "400", ... }],
218
- "sources": { "googleFonts": [...], "adobeFonts": false, "customFonts": [...] }
219
- },
220
- "spacing": { "scaleType": "8px", "commonValues": [{ "px": "16px", "rem": "1rem", "count": 42 }, ...] },
221
- "borderRadius": { "values": [{ "value": "8px", "count": 15, "confidence": "high" }, ...] },
222
- "shadows": [{ "shadow": "0 2px 4px rgba(0,0,0,0.1)", "count": 8, "confidence": "high" }, ...],
223
- "components": {
224
- "buttons": [{ "backgroundColor": "...", "color": "...", "padding": "...", ... }],
225
- "inputs": [{ "type": "input", "border": "...", "borderRadius": "...", ... }]
226
- },
227
- "breakpoints": [{ "px": "768px" }, ...],
228
- "iconSystem": [{ "name": "Font Awesome", "type": "icon-font" }, ...],
229
- "frameworks": [{ "name": "Tailwind CSS", "confidence": "high", "evidence": "class patterns" }]
230
- }
231
- ```
232
-
233
- ## Examples
234
-
235
- ### Extract Design Tokens
236
-
237
34
  ```bash
238
- # Analyze a single site (auto-saves JSON to output/stripe.com/)
239
- dembrandt stripe.com
240
-
241
- # View saved JSON files
242
- ls output/stripe.com/
243
-
244
- # Output to stdout for piping
245
- dembrandt stripe.com --json-only | jq '.colors.semantic'
246
-
247
- # Debug mode for difficult sites
248
- dembrandt example.com --debug
35
+ dembrandt <url> # Basic extraction
36
+ dembrandt bmw.de --save-output # Save JSON to output folder
37
+ dembrandt bmw.de --json-only # JSON output only (no save)
38
+ dembrandt bmw.de --debug # Visible browser
39
+ dembrandt bmw.de --dark-mode # Dark mode
40
+ dembrandt bmw.de --mobile # Mobile viewport
41
+ dembrandt bmw.de --slow # 3x timeouts
249
42
  ```
250
43
 
251
- ### Compare Competitors
252
-
253
- ```bash
254
- # Extract tokens from multiple competitors (auto-saved to output/)
255
- for site in stripe.com square.com paypal.com; do
256
- dembrandt $site
257
- done
258
-
259
- # Compare color palettes from most recent extractions
260
- jq '.colors.palette[] | select(.confidence=="high")' output/stripe.com/2025-11-22T*.json output/square.com/2025-11-22T*.json
261
-
262
- # Compare semantic colors across competitors
263
- jq '.colors.semantic' output/*/2025-11-22T*.json
264
- ```
265
-
266
- ### Integration with Design Tools
267
-
268
- ```bash
269
- # Extract and convert to custom config format
270
- dembrandt mysite.com --json-only | jq '{
271
- colors: .colors.semantic,
272
- fontFamily: .typography.sources,
273
- spacing: .spacing.commonValues
274
- }' > design-tokens.json
275
- ```
44
+ By default, results display in terminal only. Use `--save-output` to save JSON to `output/bmw.de/YYYY-MM-DDTHH-MM-SS.json`
276
45
 
277
46
  ## Use Cases
278
47
 
279
- ### Brand Audits
280
-
281
- Extract and document your company's current design system from production websites.
282
-
283
- ### Competitive Analysis
48
+ - Brand audits & competitive analysis
49
+ - Design system documentation
50
+ - Reverse engineering brands
51
+ - Multi-site brand consolidation
284
52
 
285
- Compare design systems across competitors to identify trends and opportunities.
286
-
287
- ### Design System Migration
288
-
289
- Document legacy design tokens before migrating to a new system.
290
-
291
- ### Reverse Engineering
292
-
293
- Rebuild a brand when original design guidelines are unavailable.
294
-
295
- ### Quality Assurance
296
-
297
- Verify design consistency across different pages and environments.
298
-
299
- ## Advanced Features
300
-
301
- ### Bot Detection Avoidance
302
-
303
- - Stealth mode with anti-detection scripts
304
- - Automatic fallback to visible browser on detection
305
- - Human-like interaction simulation (mouse movement, scrolling)
306
- - Custom user agent and browser fingerprinting
307
-
308
- ### Smart Retry Logic
309
-
310
- - Automatic retry on navigation failures (up to 2 attempts)
311
- - SPA hydration detection and waiting
312
- - Content validation to ensure page is fully loaded
313
- - Detailed progress logging at each step
314
-
315
- ### Comprehensive Logging
316
-
317
- - Real-time spinner with step-by-step progress
318
- - Detailed extraction metrics (colors found, styles detected, etc.)
319
- - Error context with URL, stage, and attempt information
320
- - Debug mode with full stack traces
321
-
322
- ## Troubleshooting
323
-
324
- ### Bot Detection Issues
325
-
326
- If you encounter timeouts or network errors:
327
-
328
- ```bash
329
- dembrandt example.com --debug
330
- ```
331
-
332
- This will automatically retry with a visible browser.
333
-
334
- ### Page Not Loading
335
-
336
- Some sites require longer load times. The tool waits 8 seconds for SPA hydration, but you can modify this in the source.
53
+ ## How It Works
337
54
 
338
- ### Empty Content
55
+ Uses Playwright to render the page, extracts computed styles from the DOM, analyzes color usage and confidence, groups similar typography, detects spacing patterns, and returns actionable design tokens.
339
56
 
340
- If content length is < 500 chars, the tool will automatically retry (up to 2 attempts).
57
+ ### Extraction Process
341
58
 
342
- ### Debug Mode
59
+ 1. Browser Launch - Launches Chromium with stealth configuration
60
+ 2. Anti-Detection - Injects scripts to bypass bot detection
61
+ 3. Navigation - Navigates to target URL with retry logic
62
+ 4. Hydration - Waits for SPAs to fully load (8s initial + 4s stabilization)
63
+ 5. Content Validation - Verifies page content is substantial (>500 chars)
64
+ 6. Parallel Extraction - Runs all extractors concurrently for speed
65
+ 7. Analysis - Analyzes computed styles, DOM structure, and CSS variables
66
+ 8. Scoring - Assigns confidence scores based on context and usage
343
67
 
344
- Use `--debug` to see:
68
+ ### Color Confidence
345
69
 
346
- - Browser launch confirmation
347
- - Step-by-step progress logs
348
- - Full error stack traces
349
- - Extraction metrics
70
+ - High Logo, brand elements, primary buttons
71
+ - Medium Interactive elements, icons, navigation
72
+ - Low Generic UI components (filtered from display)
73
+ - Only shows high and medium confidence colors in terminal. Full palette in JSON.
350
74
 
351
75
  ## Limitations
352
76
 
353
- - Dark mode requires `--dark-mode` flag (not automatically detected)
77
+ - Dark mode requires --dark-mode flag (not automatically detected)
354
78
  - Hover/focus states extracted from CSS (not fully interactive)
355
79
  - Canvas/WebGL-rendered sites cannot be analyzed (e.g., Tesla, Apple Vision Pro demos)
356
80
  - JavaScript-heavy sites require hydration time (8s initial + 4s stabilization)
357
81
  - Some dynamically-loaded content may be missed
358
- - Default viewport is 1920x1080 (use `--mobile` for responsive analysis)
359
-
360
- ## Architecture
361
-
362
- ```
363
- dembrandt/
364
- ├── index.js # CLI entry point, command handling
365
- ├── lib/
366
- │ ├── extractors.js # Core extraction logic with stealth mode
367
- │ └── display.js # Terminal output formatting
368
- ├── output/ # Auto-saved JSON extractions (gitignored)
369
- │ ├── stripe.com/
370
- │ │ ├── 2025-11-22T14-30-45.json
371
- │ │ └── 2025-11-22T15-12-33.json
372
- │ └── github.com/
373
- │ └── 2025-11-22T14-35-12.json
374
- ├── package.json
375
- └── README.md
376
- ```
82
+ - Default viewport is 1920x1080 (use --mobile for responsive analysis)
377
83
 
378
84
  ## Ethics & Legality
379
85
 
380
86
  Dembrandt extracts publicly available design information (colors, fonts, spacing) from website DOMs for analysis purposes. This falls under fair use in most jurisdictions (USA's DMCA § 1201(f), EU Software Directive 2009/24/EC) when used for competitive analysis, documentation, or learning.
381
87
 
382
- **Legal:** Analyzing public HTML/CSS is generally legal. Does not bypass protections or violate copyright. Check site ToS before mass extraction.
88
+ Legal: Analyzing public HTML/CSS is generally legal. Does not bypass protections or violate copyright. Check site ToS before mass extraction.
383
89
 
384
- **Ethical:** Use for inspiration and analysis, not direct copying. Respect servers (no mass crawling), give credit to sources, be transparent about data origin.
90
+ Ethical: Use for inspiration and analysis, not direct copying. Respect servers (no mass crawling), give credit to sources, be transparent about data origin.
385
91
 
386
92
  ## Contributing
387
93
 
388
- Issues and pull requests welcome. Please include:
94
+ Bugs you found? Weird websites that make it cry? Pull requests (even one-liners make me happy)?
389
95
 
390
- - Clear description of the issue/feature
391
- - Example URLs that demonstrate the problem
392
- - Expected vs actual behavior
96
+ Spam me in [Issues](https://github.com/thevangelist/dembrandt/issues) or PRs. I reply to everything.
393
97
 
394
- ## License
98
+ Let's keep the light alive together.
395
99
 
396
- MIT
100
+ @thevangelist
397
101
 
398
- ## Roadmap
102
+ ---
399
103
 
400
- - [x] Dark mode extraction (via `--dark-mode` flag)
401
- - [x] Mobile viewport support (via `--mobile` flag)
402
- - [x] Clickable terminal links for modern terminals
403
- - [ ] Animation/transition detection
404
- - [ ] Interactive state capture (hover, focus, active)
405
- - [ ] Multi-page analysis
406
- - [ ] Configuration file support
104
+ MIT do whatever you want with it.
package/index.js CHANGED
@@ -10,7 +10,7 @@
10
10
  import { program } from "commander";
11
11
  import chalk from "chalk";
12
12
  import ora from "ora";
13
- import { chromium } from "playwright";
13
+ import { chromium } from "playwright-core";
14
14
  import { extractBranding } from "./lib/extractors.js";
15
15
  import { displayResults } from "./lib/display.js";
16
16
  import { writeFileSync, mkdirSync } from "fs";
@@ -23,9 +23,11 @@ program
23
23
  .argument("<url>")
24
24
  .option("--json-only", "Output raw JSON")
25
25
  .option("-d, --debug", "Force visible browser")
26
+ .option("--save-output", "Save JSON file to output folder")
26
27
  .option("--verbose-colors", "Show medium and low confidence colors")
27
28
  .option("--dark-mode", "Extract colors from dark mode")
28
29
  .option("--mobile", "Extract from mobile viewport")
30
+ .option("--slow", "3x longer timeouts for slow-loading sites")
29
31
  .action(async (input, opts) => {
30
32
  let url = input;
31
33
  if (!url.match(/^https?:\/\//)) url = "https://" + url;
@@ -64,6 +66,7 @@ program
64
66
  navigationTimeout: 90000,
65
67
  darkMode: opts.darkMode,
66
68
  mobile: opts.mobile,
69
+ slow: opts.slow,
67
70
  });
68
71
  break;
69
72
  } catch (err) {
@@ -89,10 +92,10 @@ program
89
92
  }
90
93
  }
91
94
 
92
- spinner.succeed("Done!");
95
+ console.log();
93
96
 
94
- // Save JSON output automatically (unless --json-only)
95
- if (!opts.jsonOnly) {
97
+ // Save JSON output only if --save-output is specified
98
+ if (opts.saveOutput && !opts.jsonOnly) {
96
99
  try {
97
100
  const domain = new URL(url).hostname.replace("www.", "");
98
101
  const timestamp = new Date()
@@ -109,14 +112,14 @@ program
109
112
 
110
113
  console.log(
111
114
  chalk.dim(
112
- `\n💾 JSON saved to: ${chalk.cyan(
115
+ `💾 JSON saved to: ${chalk.hex('#8BE9FD')(
113
116
  `output/${domain}/${filename}`
114
117
  )}`
115
118
  )
116
119
  );
117
120
  } catch (err) {
118
121
  console.log(
119
- chalk.yellow(`⚠ Could not save JSON file: ${err.message}`)
122
+ chalk.hex('#FFB86C')(`⚠ Could not save JSON file: ${err.message}`)
120
123
  );
121
124
  }
122
125
  }
@@ -125,6 +128,7 @@ program
125
128
  if (opts.jsonOnly) {
126
129
  console.log(JSON.stringify(result, null, 2));
127
130
  } else {
131
+ console.log();
128
132
  displayResults(result, { verboseColors: opts.verboseColors });
129
133
  }
130
134
  } catch (err) {
@@ -140,7 +144,7 @@ program
140
144
 
141
145
  if (!opts.debug) {
142
146
  console.log(
143
- chalk.yellow(
147
+ chalk.hex('#FFB86C')(
144
148
  "\nTip: Try with --debug flag for tough sites and detailed error logs"
145
149
  )
146
150
  );