React

Knapsack for React lets you develop and test components in isolation.
View as Markdown

Knapsack for React works by scanning your specified React code locations and automatically discovering reusable components, making them instantly available in your design system.

Why This Approach:

  • Zero Manual Work - Knapsack finds and configures your components automatically
  • 🔄 Always Current - Your documentation stays in sync with code changes
  • 🎯 Intelligent - Understands different export patterns and component structures
  • 🚀 Scale Effortlessly - Handle hundreds of components without individual setup

Requirements

  • React 18 or 19
  • Knapsack 4.89.4+

Knapsack uses your React, not its own. react and react-dom go in dependencies.


Install

$npm install @knapsack/renderer-react

Configure

Minimal Setup The simplest configuration requires just specifying where your React components are located:

1// knapsack.config.js
2const { KnapsackReactRenderer } = require('@knapsack/renderer-react');
3
4module.exports = configureKnapsack({
5 templateRenderers: [
6 new KnapsackReactRenderer({
7 codeSrcs: [{ path: './src/components/**/*.tsx' }],
8 }),
9 ],
10};

Full Configuration Example Here’s a comprehensive example showing all available options:

1const { KnapsackReactRenderer } = require('@knapsack/renderer-react');
2
3module.exports = configureKnapsack({
4 templateRenderers: [
5 new KnapsackReactRenderer({
6 // Code discovery paths
7 codeSrcs: [
8 { path: '@my-design-system/react' },
9 { path: './src/components/**/*.{tsx,jsx}' },
10 {
11 path: '@mui/material/*',
12 filter: (path) => !path.includes('internal'),
13 },
14 ],
15
16 // React Strict Mode
17 disableReactStrictMode: true,
18
19 // Demo wrapper for all components
20 demoWrapperPath: './src/demo-wrapper.tsx',
21
22 // Webpack customization
23 webpackConfig: {
24 resolve: {
25 alias: {
26 '@': path.resolve(__dirname, 'src'),
27 },
28 },
29 module: {
30 rules: [
31 {
32 test: /\\.module\\.css$/,
33 use: ['style-loader', 'css-loader'],
34 },
35 ],
36 },
37 },
38 }),
39 ],
40};

Code Sources

The codeSrcs array tells Knapsack where to find your React components and how to process them. The renderer will scan these paths, find React component exports, and make them available in the Knapsack UI for documentation and demos.

Local Components

Paths are relative to knapsack.config.js

1codeSrcs: [
2 // Specific directory
3 { path: './src/components/**/*.tsx' },
4
5 // Multiple file extensions
6 { path: './src/ui/**/*.{tsx,jsx,ts,js}' },
7
8 // Specific component types
9 { path: './src/components/atoms/*.tsx' },
10 { path: './src/components/molecules/*.tsx' },
11];
External Libraries

Ensure that any external library is included in your package dependencies

1codeSrcs: [
2 // Entire package
3 { path: '@radix-ui/themes' },
4 { path: '@chakra-ui/react' },
5
6 // Package sub-paths
7 { path: '@mui/material/*' },
8 { path: '@my-org/design-system/components/*' },
9];
Smart Filtering

Use filters to control exactly which components are discovered:

1codeSrcs: [
2 {
3 path: './src/**/*.tsx',
4 filter: (path) => {
5 // Only include components, exclude utilities and tests
6 return (
7 path.includes('/components/') &&
8 !path.includes('.test.') &&
9 !path.includes('.stories.')
10 );
11 },
12 },
13 {
14 path: '@mui/material/*',
15 filter: (path) => {
16 // Exclude problematic MUI exports
17 const excludedPaths = [
18 '@mui/material/index',
19 '@mui/material/styles/index',
20 '@mui/material/utils',
21 ];
22 return !excludedPaths.some((excluded) => path.includes(excluded));
23 },
24 },
25];

Demo Wrapper

A demo wrapper is a React component that wraps around each of your components when they’re rendered in Knapsack. This is essential for providing context like theme providers, CSS resets, or global styles.

Additionally, the props contain useful information beyond just props.children for your custom usage: props.pattern, props.template, props.demo, and props.patternsUsed. See the TypeScript definition for more details.

Setup

1. Create a Wrapper: Create a file (e.g., src/demo-wrapper.tsx):

1import React from 'react';
2import { ThemeProvider } from 'styled-components';
3import { theme } from './theme';
4import './global-styles.css';
5
6interface DemoWrapperProps {
7 children: React.ReactNode;
8}
9
10export const DemoWrapper: React.FC<DemoWrapperProps> = ({ children }) => {
11 return (
12 <ThemeProvider theme={theme}>
13 <div className="demo-wrapper">{children}</div>
14 </ThemeProvider>
15 );
16};

2. Add your Wrapper Path Reference your wrapper in the renderer configuration:

1new KnapsackReactRenderer({
2 demoWrapperPath: './src/demo-wrapper.tsx',
3 codeSrcs: [
4 // your code sources
5 ],
6});
Common Examples
1// 1. Theme Provider Wrapper
2import { ThemeProvider } from '@my-org/theme';
3import { defaultTheme } from './themes';
4
5export const DemoWrapper = ({ children }) => (
6 <ThemeProvider theme={defaultTheme}>{children}</ThemeProvider>
7);
8
9// 2. CSS-in-JS Provider
10import { ChakraProvider } from '@chakra-ui/react';
11import { theme } from './chakra-theme';
12
13export const DemoWrapper = ({ children }) => (
14 <ChakraProvider theme={theme}>{children}</ChakraProvider>
15);
16
17// 3. Multiple Providers
18import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
19import { ThemeProvider } from 'styled-components';
20import { theme } from './theme';
21
22const queryClient = new QueryClient();
23
24export const DemoWrapper = ({ children }) => (
25 <QueryClientProvider client={queryClient}>
26 <ThemeProvider theme={theme}>
27 <div className="demo-container">{children}</div>
28 </ThemeProvider>
29 </QueryClientProvider>
30);

React Strict Mode

By default, react strict mode is enabled. If you need to disable React Strict mode for your components, you can set this option to true in the configuration:

1// knapsack.config.js
2const { KnapsackReactRenderer } = require('@knapsack/renderer-react');
3
4module.exports = configureKnapsack({
5 templateRenderers: [
6 new KnapsackReactRenderer({
7 disableReactStrictMode: true,
8 }),
9 ],
10};

Webpack Configuration

The React renderer uses Webpack under the hood to process your components. You can provide custom webpack configuration to handle React-specific requirements like babel-loader, JSX transformation, and other build tools.

These webpack configurations are your responsibility to implement correctly. Knapsack provides the integration but you handle the webpack setup.

Common Use Cases

You might need to configure webpack for:

  • Path aliases - Create import shortcuts like @/components/Button
  • CSS processing - Handle CSS modules, SCSS, styled-components, etc.
  • Asset handling - Process images, fonts, and other static files
  • TypeScript configuration - Set up TypeScript compilation and path mapping
  • Third-party library compatibility - Configure loaders for specific libraries
Common Examples

Path Aliases

1webpackConfig: {
2 resolve: {
3 alias: {
4 '@': path.resolve(__dirname, 'src'),
5 '@components': path.resolve(__dirname, 'src/components'),
6 '@utils': path.resolve(__dirname, 'src/utils')
7 }
8 }
9}

CSS Modules

1webpackConfig: {
2 resolve: {
3 alias: {
4 '@': path.resolve(__dirname, 'src'),
5 '@components': path.resolve(__dirname, 'src/components'),
6 '@utils': path.resolve(__dirname, 'src/utils')
7 }
8 }
9}

SCSS Support

1webpackConfig: {
2 module: {
3 rules: [
4 {
5 test: /\\.scss$/,
6 use: ['style-loader', 'css-loader', 'sass-loader'],
7 },
8 ];
9 }
10}

Asset Handling

1webpackConfig: {
2 module: {
3 rules: [
4 {
5 test: /\\.(png|jpg|gif|svg)$/,
6 type: 'asset/resource',
7 },
8 {
9 test: /\\.(woff|woff2|eot|ttf|otf)$/,
10 type: 'asset/resource',
11 },
12 ];
13 }
14}

TypeScript Path Mapping

1webpackConfig: {
2 resolve: {
3 alias: {
4 // Map tsconfig paths
5 '@/*': path.resolve(__dirname, 'src/*'),
6 '@components/*': path.resolve(__dirname, 'src/components/*')
7 }
8 }
9}