Work with Vite
This guide covers setting up React Signify with Vite from scratch, including project creation, React configuration, and React Signify integration.
Prerequisites
- Node.js >= 16.0.0
- NPM, Yarn, pnpm, or Bun package manager
Project Setup
1. Create New Vite + React Project
Using NPM
bash
# JavaScript
npm create vite@latest my-signify-app -- --template react
# TypeScript (Recommended)
npm create vite@latest my-signify-app -- --template react-ts
cd my-signify-app
npm install
Using Yarn
bash
# JavaScript
yarn create vite my-signify-app --template react
# TypeScript (Recommended)
yarn create vite my-signify-app --template react-ts
cd my-signify-app
yarn install
Using pnpm
bash
# JavaScript
pnpm create vite my-signify-app --template react
# TypeScript (Recommended)
pnpm create vite my-signify-app --template react-ts
cd my-signify-app
pnpm install
Using Bun
bash
# JavaScript
bun create vite my-signify-app --template react
# TypeScript (Recommended)
bun create vite my-signify-app --template react-ts
cd my-signify-app
bun install
2. Install React Signify
bash
# NPM
npm install react-signify
# Yarn
yarn add react-signify
# pnpm
pnpm add react-signify
# Bun
bun add react-signify
Vite Configuration
Basic Configuration
Update your vite.config.ts
for optimal React Signify performance:
typescript
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
optimizeDeps: {
include: ["react-signify"],
},
build: {
rollupOptions: {
output: {
manualChunks: {
"react-signify": ["react-signify"],
},
},
},
},
});
Advanced Configuration
For larger applications with optimization:
typescript
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
optimizeDeps: {
include: ["react-signify"],
},
build: {
rollupOptions: {
output: {
manualChunks: (id) => {
if (id.includes("react-signify")) {
return "react-signify";
}
if (id.includes("node_modules")) {
return "vendor";
}
},
},
},
chunkSizeWarningLimit: 1000,
},
server: {
port: 3000,
open: true,
},
});
TypeScript Configuration
tsconfig.json Setup
If using TypeScript, ensure your tsconfig.json
is optimized:
json
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
Project Structure
Files You'll Create
src/
├── components/
│ ├── Counter.tsx
│ └── CounterButton.tsx
├── store/
│ └── counter.ts
├── App.tsx
├── main.tsx
└── index.css
React Signify Integration
1. Create Store File
Create a store file to manage your counter state:
tsx
// src/store/counter.ts
import { signify } from "react-signify";
export const sCounter = signify(0);
2. Create Main Component (Display with use
)
Create the main component that displays the counter value:
tsx
// src/components/Counter.tsx
import React from "react";
import { sCounter } from "../store/counter";
import CounterButton from "./CounterButton";
export default function Counter() {
const count = sCounter.use(); // Use to display value
return (
<div>
<h2>Counter: {count}</h2>
<CounterButton />
</div>
);
}
3. Create Child Component (Update with set
)
Create a child component that updates the counter:
tsx
// src/components/CounterButton.tsx
import React from "react";
import { sCounter } from "../store/counter";
export default function CounterButton() {
const handleIncrement = () => {
sCounter.set(prev => {
prev.value += 1; // Set to update value directly
});
};
return <button onClick={handleIncrement}>+1</button>;
}
4. Update Main App
tsx
// src/App.tsx
import React from "react";
import Counter from "./components/Counter";
import "./App.css";
function App() {
return (
<div className="App">
<h1>Vite + React + React Signify</h1>
<Counter />
</div>
);
}
export default App;
5. Update Main Entry
tsx
// src/main.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
import "./index.css";
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Development Tools
ESLint Configuration
Add to your .eslintrc.cjs
:
javascript
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
"eslint:recommended",
"@typescript-eslint/recommended",
"plugin:react-hooks/recommended",
],
ignorePatterns: ["dist", ".eslintrc.cjs"],
parser: "@typescript-eslint/parser",
plugins: ["react-refresh"],
rules: {
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
"react-hooks/exhaustive-deps": "warn",
"react-hooks/rules-of-hooks": "error",
"@typescript-eslint/no-unused-vars": "error",
},
};
Build and Deployment
Build for Production
bash
# NPM
npm run build
# Yarn
yarn build
# pnpm
pnpm build
# Bun
bun run build
Preview Production Build
bash
# NPM
npm run preview
# Yarn
yarn preview
# pnpm
pnpm preview
# Bun
bun run preview
Deploy to Vercel
bash
# Install Vercel CLI
npm i -g vercel
# Deploy
vercel
Deploy to Netlify
bash
# Build first
npm run build
# Deploy dist folder to Netlify
# Or connect your Git repository to Netlify
Performance Optimization
Bundle Analysis
bash
# Install bundle analyzer
npm install --save-dev rollup-plugin-visualizer
# Add to vite.config.ts
import { visualizer } from 'rollup-plugin-visualizer';
export default defineConfig({
plugins: [
react(),
visualizer({
filename: 'dist/stats.html',
open: true,
}),
],
});
Tree Shaking
React Signify supports tree shaking out of the box:
tsx
// ✅ Good - Tree shakable
import { signify } from "react-signify";
// ❌ Avoid - Imports everything
import * as ReactSignify from "react-signify";
Troubleshooting
Common Issues
1. "Cannot resolve module 'react-signify'"
bash
# Clear cache and reinstall
rm -rf node_modules
rm package-lock.json # or yarn.lock, pnpm-lock.yaml
npm install
2. TypeScript errors
bash
# Ensure React types are installed
npm install --save-dev @types/react @types/react-dom
3. Vite hot reload issues
tsx
// Add to vite.config.ts
export default defineConfig({
server: {
hmr: {
overlay: false,
},
},
});
4. Build errors
bash
# Check for TypeScript errors
npx tsc --noEmit
# Clear Vite cache
rm -rf node_modules/.vite
Testing Setup
Vitest Configuration
bash
npm install --save-dev vitest @testing-library/react @testing-library/jest-dom
typescript
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: "jsdom",
setupFiles: ["./src/test/setup.ts"],
},
});
typescript
// src/test/setup.ts
import "@testing-library/jest-dom";
Example Test
tsx
// src/components/__tests__/Counter.test.tsx
import { render, screen, fireEvent } from "@testing-library/react";
import { describe, it, expect, beforeEach } from "vitest";
import Counter from "../Counter";
import { sCounter } from "../../store/counter";
describe("Counter", () => {
beforeEach(() => {
sCounter.reset();
});
it("renders counter with initial value", () => {
render(<Counter />);
expect(screen.getByText("Counter: 0")).toBeInTheDocument();
});
it("increments counter when + button is clicked", () => {
render(<Counter />);
const incrementButton = screen.getByText("+");
fireEvent.click(incrementButton);
expect(screen.getByText("Counter: 1")).toBeInTheDocument();
});
});
Next Steps
After successful setup:
- 📖 Understanding Signify - Learn core concepts
- 🚀 Quick Start Guide - Build more examples
- 🏗️ Project Structure - Advanced organization
- 🎯 TypeScript Guide - Advanced TypeScript usage
- 📚 API Reference - Complete API guide
Having issues with Vite + React Signify? Create an issue on GitHub or check our discussions.