W3C Design Tokens Standard Compliant - Figma-Exclusive Design Token Management Application
ζ₯ζ¬θͺηγ―γγ‘γ / Japanese version
This application is a W3C Design Tokens Community Group standards-compliant token management tool with full compatibility with the Figma Design Tokens Manager plugin.
- Full Figma Compatibility: Bidirectional data exchange with the Design Tokens Manager plugin
- W3C Standards Compliant: Fully compatible with the W3C Design Tokens Community Group specification
- Intuitive UI: Three display modes - Standard, Compact, and Table
- Real-time Editing: Edit values, roles, and descriptions with double-click
- Dark Mode Support: Automatic switching linked to system settings
- TypeScript: Complete type safety and IntelliSense support
# Install dependencies
npm install
# Start development server
npm run dev
# Production build
npm run build- Load Sample Data: Click "Load Figma Sample Data" button to display W3C format samples
- Import JSON File: Use "Choose JSON file" to load JSON exported from Figma
- Paste JSON Directly: Use "Paste JSON" to import data from clipboard
- Edit Tokens: Double-click any field to edit values
- Export Data: Click "Export" button to output W3C format JSON
| Type | Description | Example |
|---|---|---|
color |
Color tokens | #2164D1, rgb(33, 100, 209) |
typography |
Typography tokens | Font family, size, weight |
spacing |
Spacing tokens | 16px, 1rem, 2em |
size |
Size tokens | 24px, 2rem |
borderRadius |
Border radius tokens | 8px, 50% |
opacity |
Opacity tokens | 0.5, 0.8 |
borderColor |
Border color tokens | #E0E0E0 |
shadow |
Shadow tokens | 0px 2px 4px rgba(0,0,0,0.1) |
breakpoint |
Breakpoint tokens | 768px, 1200px |
icon |
Icon tokens | Size and stroke settings |
- Open the Design Tokens Manager plugin in Figma
- Select the Export tab
- Choose JSON format
- Click Export button to download the JSON file
- Import the JSON file in this app
- Click the Export button in this app
- Copy to Clipboard or Download JSON file
- Open the Design Tokens Manager plugin in Figma
- Paste JSON or select file in the Import tab
- Automatically recognized as W3C format and imported
- Frontend: React 18 + TypeScript
- Styling: Tailwind CSS + Dark mode support
- Icons: Lucide React
- Build Tool: Vite
- State Management: React Hooks + localStorage
- Standards: W3C Design Tokens Community Group
{
"figma": {
"color": {
"primary": {
"main": {
"$type": "color",
"$value": "#2164D1",
"$role": "Brand color",
"$description": "Color used for primary actions and branding"
}
}
},
"typography": {
"heading": {
"h1": {
"$type": "typography",
"$value": {
"fontFamily": "Inter",
"fontSize": 32,
"fontWeight": 700,
"lineHeight": 1.25
},
"$description": "Main heading"
}
}
}
}
}- Standard: Card format displaying detailed information
- Compact: Compact list view
- Table: Table format with sort and filter support
- Value Editing: Inline editing with double-click
- Role Setting: Clarify token purpose
- Description Addition: Describe detailed usage
- Real-time Updates: Changes reflected immediately
- Keyword Search: Search by token name, value, or description
- Type Filter: Display only specific token types
- Bulk Operations: Delete multiple selections
# Start development server
npm run dev
# Production build
npm run build
# Preview build
npm run preview
# Run linter
npm run lint# Install dependencies (first time only)
npm install
# Start development server
npm run devOpen http://localhost:5173 in your browser.
When the app starts, sample data is automatically loaded. This allows you to immediately see the token structure and usage.
- Open the Design Tokens Manager plugin in Figma
- Select the Export tab
- Choose JSON format and click Export
- Click the "Choose JSON file" button in this app
- Select the downloaded JSON file
- Tokens are automatically loaded and displayed
- Click the "Paste JSON" button in the app
- A modal opens - paste your JSON string
- Click the "Import" button
- If the format is correct, tokens will be displayed
- Click the "Load Figma Sample Data" button
- W3C standard format sample tokens are displayed
- Use this data as a reference to create your own tokens
Use the segment control at the top of the screen to switch between three display modes:
- Standard: Card format displaying details for each token (default)
- Compact: Compact list view
- Table: Table format view with sortable columns
To edit token values:
- Double-click the field you want to edit (value, role, description)
- Inline editing mode is activated, allowing text input
- Press Enter key or click outside to confirm
- Press Esc key to cancel editing
- Changes are automatically saved
Editable fields:
- Value: The actual token value (color code, font size, etc.)
- Role: The token's role or purpose
- Description: Detailed explanation of the token
- Enter keywords in the search box at the top of the screen
- Token names, values, and descriptions are searched with partial matching
- Search results are displayed in real-time
- Click the X icon to clear the search
- Select a specific token type from the "Type" dropdown
- Only tokens of the selected type are displayed
- Select "All Types" to reset the filter
To delete multiple tokens at once:
- Click the "Bulk Delete Mode" button
- Check the checkboxes on the left of tokens you want to delete
- Once selections are complete, click "Delete Selected Tokens" button
- A confirmation dialog appears - click "Delete"
- Click "Done" button to exit bulk delete mode
- Click the "Export" button
- The export preview modal opens
- Choose from the following options:
- W3C Design Tokens (JSON): Figma-compatible W3C standard format (recommended)
- Copy to Clipboard: Copy JSON to clipboard
- Download JSON: Download as JSON file
- Export JSON using this app
- Open the Design Tokens Manager plugin in Figma
- Select the Import tab
- Paste JSON or upload file
- Automatically recognized as W3C format and import completed
- All changes are automatically saved to browser's localStorage
- Page reloads preserve the previous state
- No manual saving required
- Click the "Force Refresh" button (top right of page)
- All data is cleared and reverts to initial sample data
- Warning: This operation cannot be undone
Click the moon/sun icon in the top right corner to toggle between dark mode and light mode. Settings are automatically saved.
- Verify JSON format is correct
- Check browser console for error messages
- Try "Force Refresh" to return to initial state
- Verify browser localStorage is enabled
- Data won't be saved in private browsing mode
- Clear browser cache and retry
- Verify export format is "W3C Design Tokens (JSON)"
- Check for JSON syntax errors
- Verify Design Tokens Manager plugin is latest version
figma-json-token-manager/
βββ src/
β βββ components/ # React components
β β βββ TokenGroup.tsx # Token group display
β β βββ TokenEditor.tsx # Token editing UI
β β βββ TokenTableView.tsx # Table view
β β βββ BulkDeleteMode.tsx # Bulk delete feature
β β βββ ConfirmDialog.tsx # Confirmation dialog
β β βββ ExportPreviewModal.tsx # Export modal
β β βββ PasteJsonModal.tsx # JSON paste modal
β β βββ ErrorDisplay.tsx # Error display
β β βββ HelpModal.tsx # Help modal
β βββ hooks/ # Custom hooks
β β βββ useAppState.ts # App-wide state management
β β βββ useTokenManagement.ts # Token management logic
β β βββ useSearchAndFilter.ts # Search & filter functionality
β β βββ useBulkDelete.ts # Bulk delete logic
β β βββ useKeyboardShortcuts.ts # Keyboard shortcuts
β β βββ useEffects.ts # Side effects management
β β βββ useUIHelpers.ts # UI helper functions
β βββ utils/ # Utility functions
β β βββ tokenUtils.ts # Core token operations
β β βββ tokenConverter.ts # Format conversion
β β βββ colorUtils.ts # Color manipulation utilities
β βββ data/ # Sample data
β β βββ initialMockData.ts # Initial mock data
β β βββ w3cSampleTokens.ts # W3C samples
β βββ types.ts # TypeScript type definitions
β βββ App.tsx # Main app component
β βββ main.tsx # Entry point
βββ CLAUDE.md # Claude Code guidelines
βββ README.md # This file
# Clone repository
git clone https://github.com/boxpistols/figma-json-token-manager.git
cd figma-json-token-manager
# Install dependencies
npm install
# Start development server (hot reload enabled)
npm run dev
# TypeScript type check
npx tsc --noEmit
# Run linter
npm run lint
# Auto-fix lint errors
npm run fix# Production build
npm run build
# Preview build result
npm run preview
# Build artifacts generated in dist/ folder- ESLint: Integrates TypeScript, React, and Prettier rules
- Config file:
eslint.config.js - Key rules:
- Proper use of React Hooks
- Strict TypeScript type checking
- Unified code formatting with Prettier
- Strict Mode enabled
- Guarantees complete type safety
- Config file:
tsconfig.json
Step 1: Update type definitions (src/types.ts)
export interface DesignToken {
$type:
| 'color'
| 'typography'
// Add new type
| 'newType';
// ...
}Step 2: Update validation (src/utils/tokenUtils.ts:validateToken)
if (![
'color',
'typography',
// ...
'newType', // Add
].includes(designToken.$type)) {
// ...
}Step 3: Update flattening process (src/utils/tokenUtils.ts:flattenTokens)
- Add processing for new type in
isArrayFormatbranch
Step 4: Add UI component support
- Add display logic to
TokenGroup.tsxorTokenEditor.tsx
Best Practices:
- Place components in
src/components/ - Clearly define Props types
- Separate logic with custom hooks
- Style with Tailwind CSS
Example: New modal component
// src/components/NewModal.tsx
import { X } from 'lucide-react';
interface NewModalProps {
isOpen: boolean;
onClose: () => void;
// Other props
}
export default function NewModal({ isOpen, onClose }: NewModalProps) {
if (!isOpen) return null;
return (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
{/* Modal content */}
</div>
);
}Location: src/hooks/
Naming Convention: Use use prefix
Example: New hook
// src/hooks/useNewFeature.ts
import { useState, useCallback } from 'react';
export function useNewFeature() {
const [state, setState] = useState(initialValue);
const action = useCallback(() => {
// Logic
}, [dependencies]);
return { state, action };
}User action (file upload/JSON paste)
β
handleFileUpload / handlePasteJson (useTokenManagement.ts)
β
validateToken() (tokenUtils.ts) - Validation
β
setTokens() - Save to React state
β
saveTokensToStorage() - Persist to localStorage
β
useEffect trigger (useTokenManagement.ts)
β
flattenTokens() - Flatten data
β
groupTokensByType() - Group by type
β
UI re-render
User double-clicks field
β
Inline edit mode activated (TokenEditor.tsx)
β
Change value and confirm
β
handleTokenUpdate() (useTokenManagement.ts)
β
Array format: Update token in array directly
W3C format: Reconstruct nested object
β
setTokens() - Update React state
β
useEffect trigger β Auto-save to localStorage
β
UI re-render
Export button click
β
ExportPreviewModal displayed
β
Select format (W3C Design Tokens)
β
convertToW3CFormat() (tokenConverter.ts)
β
Array format β Convert to W3C format
W3C format β Output as-is
β
Copy to clipboard / Download JSON file
design-tokens-state: Token datadarkMode: Dark mode setting
- Data saved in JSON format
- Capacity limit: Approximately 5-10MB (browser dependent)
- Not persisted in private browsing mode
// In browser developer console
// View saved data
console.log(JSON.parse(localStorage.getItem('design-tokens-state')));
// Clear data
localStorage.removeItem('design-tokens-state');Key logging points:
tokenUtils.ts: Flattening process logstokenConverter.ts: Format conversion logsuseTokenManagement.ts: Data update logs
// Check flattenTokens result
console.log('Flattened tokens:', flattenedTokens);
// Check type detection
console.log('Is array format:', isArrayFormat(data));
// Check localStorage contents
console.log('Stored data:', loadTokensFromStorage());useMemoto prevent recalculationuseCallbackto stabilize callbacksReact.memoto prevent component re-renders
- Introduce virtual scrolling for large token sets (1000+)
- Debounce search processing (currently not implemented)
# Remove node_modules and reinstall
rm -rf node_modules package-lock.json
npm install
# Clear cache
npm cache clean --force# Run TypeScript type check
npx tsc --noEmit
# Identify and fix error locations- Restart Vite server
- Clear browser cache
- Check
vite.config.tsconfiguration
main: Stable version (production)develop: Development versionfeature/*: Feature addition branchesfix/*: Bug fix branches
- Develop in
feature/*orfix/*branch - Create Pull Request
- Code review
- Merge to
develop - Test verification
- Merge to
mainand release
Adopts Semantic Versioning (SemVer):
MAJOR.MINOR.PATCH- Example:
1.0.0β1.1.0(new feature) β1.1.1(bug fix)
Important Notes:
- Be careful of data loss during conversion processing as both Array and W3C formats are supported
- Handling of
roleanddescriptionfields differs by format (details below) - Be careful with path joining when using nested W3C format
Recommended Measures:
- Always execute validation with
validateToken() - Compare token counts before and after format conversion
- Add unit tests (currently not implemented)
After detailed codebase analysis, the following potential data integrity issues have been identified.
File: src/utils/tokenConverter.ts
Problem:
- When converting Array format β W3C format,
rolefield is mapped to$description(lines 56-57, 68, etc.) - W3C format can have both
$roleand$description, but when converting from Array format,roleconverts to$description - During reverse conversion (W3C β Array),
$rolefield information may be lost
Concrete Example:
// Array format
{
name: "primary",
value: "#2c1b9c",
role: "Brand color", // role field
description: "Main heading" // description field
}
// Converted to W3C format
{
"$type": "color",
"$value": "#2c1b9c",
"$description": "Brand color" // role mapped to $description
// Original description is lost!
}Impact Scope:
- When exporting tokens with both
roleanddescriptionin Array format to W3C format descriptioninformation is lost
Recommended Fix:
// In convertToStandardFormat() in tokenConverter.ts
standardFormat[color.name] = {
$type: 'color',
$value: color.value,
$role: color.role, // Save as $role
$description: color.description, // Save as $description
};File: src/utils/tokenUtils.ts:flattenTokens()
Problem:
- Deeply nested W3C format (e.g.,
figma.color.primary.main) is correctly processed, but unclear if nesting structure can be fully restored during reverse conversion convertToArrayFormat()assumes 1 or 2 nesting levels, potentially unexpected behavior with 3+ levels
Concrete Example:
{
"figma": {
"design-system": {
"color": {
"brand": {
"primary": {
"$type": "color",
"$value": "#2c1b9c"
}
}
}
}
}
}Unclear if such 5-level nesting can be correctly flattened and reconstructed.
Impact Scope:
- Data exported from Figma projects with complex nesting structures
Recommended Fix:
- Improve
convertToArrayFormat()path processing to work recursively - Or add option to preserve nesting structure on export
File: src/utils/tokenUtils.ts:flattenTokens() (lines 75-103)
Problem:
- When W3C format Typography token has
fontSizeas string ("16px"), it's converted to number - However, Array format expects
fontSizeto be numeric type - Unclear if this conversion is performed consistently and correctly reverted to string on export
Concrete Example:
// W3C format (input)
{
"$type": "typography",
"$value": {
"fontSize": "16px", // String
"fontWeight": "700" // String
}
}
// After flattening
{
type: "typography",
value: {
fontSize: 16, // Converted to number
fontWeight: 700 // Converted to number
}
}Impact Scope:
- Type mismatch may occur when editing/exporting Typography tokens
Recommended Fix:
- Add logic to convert numeric fontSize to string (
"16px") on export - Or unify internal representation (all numbers or all strings)
File: src/utils/tokenUtils.ts:saveTokensToStorage()
Problem:
- Insufficient error handling when exceeding localStorage capacity limit (typically 5-10MB)
- Currently only outputs
console.errorlog
Impact Scope:
- When handling large token sets (thousands of tokens)
- Users not notified of errors, data not saved
Recommended Fix:
export function saveTokensToStorage(tokens: TokenData) {
try {
const jsonString = JSON.stringify(tokens);
// Size check
const sizeInMB = new Blob([jsonString]).size / (1024 * 1024);
if (sizeInMB > 5) {
console.warn(`Token data size: ${sizeInMB.toFixed(2)}MB`);
// Display warning to user
return { success: false, error: 'Data too large' };
}
localStorage.setItem(STORAGE_KEY, jsonString);
return { success: true };
} catch (error) {
console.error('Error saving tokens to localStorage:', error);
return { success: false, error };
}
}File: src/hooks/useTokenManagement.ts:handleTokenUpdate()
Problem:
- Different logic used to update tokens for Array and W3C formats
- Path joining method (slash-delimited) may be inconsistent
- Reconstructing nested objects when updating W3C format is complex
Impact Scope:
- Wrong token may be updated when editing
- Especially when nesting is deep
Recommended Fix:
- Create utility function to handle path processing uniformly
- Add test cases (currently not implemented)
-
Fix handling of
roleanddescriptionduring Array β W3C conversion- File:
src/utils/tokenConverter.ts - To prevent data loss
- File:
-
Unify Typography
fontSizetype conversion- Files:
src/utils/tokenUtils.ts,src/utils/tokenConverter.ts - To prevent type errors on export
- Files:
-
Strengthen localStorage error handling
- File:
src/utils/tokenUtils.ts - Improve user experience
- File:
-
Improve handling of deeply nested structures
- File:
src/utils/tokenConverter.ts - Support complex Figma projects
- File:
-
Add unit tests
- Create tests for all utility functions
- Continuously guarantee data integrity
-
Further strengthen type safety
- More strict type definitions
- Add runtime validation
Figma Design Tokens Manager-Exclusive App - W3C Design Tokens Standard Compliant