kriasoft / kriasoft/react-starter-kit
Implement Jotai atoms for global state management
- Dominant language
- TypeScript
- Stars
- 23.7k
- Forks
- 4.2k
- Avg merge
- 2h 6m
- Merged PRs (30d)
- 3
Description
## 📋 Overview
We need to implement a structured global state management system using Jotai atoms. This will help centralize and organize our application state in a type-safe, reactive way. The goal is to create domain-specific atom files that will manage different aspects of our application state.
## 🎯 Objective
Create a well-organized atoms directory structure with domain-specific atom files for managing global application state using Jotai's atomic state management pattern.
## 📁 Directory Structure to Create
```
apps/web/atoms/
├── user.ts # Authentication and user state
├── theme.ts # UI preferences and theming
├── settings.ts # Application configuration
└── index.ts # Clean re-exports
```
## ✅ Tasks
### 1. Create `apps/web/atoms/user.ts`
Implement atoms for user authentication and profile state:
```typescript
import { atom } from 'jotai';
import { atomWithStorage } from 'jotai/utils';
// Primitive atoms (base state)
export const userAtom = atom(null);
export const isAuthenticatedAtom = atom(false);
export const authTokenAtom = atomWithStorage('authToken', null);
// Derived atoms (computed values)
export const userDisplayNameAtom = atom(
(get) => get(userAtom)?.displayName || get(userAtom)?.email || 'Guest'
);
export const userInitialsAtom = atom((get) => {
const user = get(userAtom);
if (\!user) return 'G';
const name = user.displayName || user.email;
return name
.split(' ')
.map(n => n[0])
.join('')
.toUpperCase()
.slice(0, 2);
});
```
### 2. Create `apps/web/atoms/theme.ts`
Implement atoms for UI preferences and theming:
```typescript
import { atom } from 'jotai';
import { atomWithStorage } from 'jotai/utils';
type Theme = 'light' | 'dark' | 'system';
type ColorScheme = 'blue' | 'green' | 'purple' | 'orange';
// Primitive atoms with localStorage persistence
export const themeAtom = atomWithStorage('theme', 'system');
export const colorSchemeAtom = atomWithStorage('colorScheme', 'blue');
export const sidebarCollapsedAtom = atomWithStorage('sidebarCollapsed', false);
// Derived atoms
export const resolvedThemeAtom = atom((get) => {
const theme = get(themeAtom);
if (theme \!== 'system') return theme;
// Check system preference
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
});
export const themeClassAtom = atom((get) => {
const theme = get(resolvedThemeAtom);
const color = get(colorSchemeAtom);
return `theme-${theme} color-${color}`;
});
```
### 3. Create `apps/web/atoms/settings.ts`
Implement atoms for application configuration:
```typescript
import { atom } from 'jotai';
import { atomWithStorage } from 'jotai/utils';
interface AppSettings {
notifications: {
email: boolean;
push: boolean;
sound: boolean;
};
privacy: {
shareAnalytics: boolean;
showOnlineStatus: boolean;
};
locale: string;
timezone: string;
}
// Default settings
const defaultSettings: AppSettings = {
notifications: {
email: true,
push: true,
sound: false,
},
privacy: {
shareAnalytics: false,
showOnlineStatus: true,
},
locale: 'en-US',
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
};
// Primitive atom with localStorage persistence
export const settingsAtom = atomWithStorage('appSettings', defaultSettings);
// Derived atoms for specific settings
export const notificationsEnabledAtom = atom(
(get) => {
const settings = get(settingsAtom);
return settings.notifications.email || settings.notifications.push;
}
);
export const localeAtom = atom(
(get) => get(settingsAtom).locale,
(get, set, locale: string) => {
const settings = get(settingsAtom);
set(settingsAtom, { ...settings, locale });
}
);
```
### 4. Create `apps/web/atoms/index.ts`
Create clean re-exports for all atoms:
```typescript
// User atoms
export {
userAtom,
isAuthenticatedAtom,
authTokenAtom,
userDisplayNameAtom,
userInitialsAtom,
} from './user';
// Theme atoms
export {
themeAtom,
colorSchemeAtom,
sidebarCollapsedAtom,
resolvedThemeAtom,
themeClassAtom,
} from './theme';
// Settings atoms
export {
settingsAtom,
notificationsEnabledAtom,
localeAtom,
} from './settings';
```
## 💡 Implementation Tips
1. **Use TypeScript**: Define proper types for all atom values
2. **Leverage atomWithStorage**: Use this for values that should persist across sessions
3. **Create derived atoms**: Use read-only atoms for computed values
4. **Keep atoms focused**: Each atom should represent a single piece of state
5. **Use atom families**: For dynamic collections of similar atoms (if needed)
## 📚 Example Usage in Components
```tsx
import { useAtom, useAtomValue } from 'jotai';
import { userAtom, themeAtom, userDisplayNameAtom } from '@/atoms';
function UserProfile() {
const [user, setUser] = useAtom(userAtom);
const displayName = useAtomValue(userDisplayNameAtom);
const [theme, setTheme] = useAtom(themeAtom);
return (
Welcome, {displayName}\!
setTheme(theme === 'dark' ? 'light' : 'dark')}>
Toggle Theme
);
}
```
## 🧪 Testing Requirements
- Write unit tests for derived atoms logic
- Test localStorage persistence for atomWithStorage
- Verify atom updates trigger component re-renders
- Test edge cases (null users, invalid settings, etc.)
## 📖 Resources
- **Existing store setup**: Check `apps/web/lib/store.ts` for current Jotai configuration
- **Jotai Documentation**: https://jotai.org/docs/core/atom
- **Jotai Utils**: https://jotai.org/docs/utilities/storage
- **Best Practices**: https://jotai.org/docs/guides/atoms-in-atom
## ⚡ Priority
**High** - This is foundational work that will improve state management across the entire application.
## 🎓 Good First Issue Notes
This is an excellent first issue because:
- Clear, well-defined scope
- Good introduction to our codebase structure
- Learn modern React state management patterns
- No complex business logic required
- Can be implemented incrementally
## ❓ Questions?
Feel free to ask questions in the comments\! We're here to help you succeed with this contribution.
## 🔍 Definition of Done
- [ ] All atom files created with proper TypeScript types
- [ ] Atoms follow Jotai best practices
- [ ] Clean re-exports in index.ts
- [ ] Code follows project conventions (functional, modern TypeScript)
- [ ] Basic unit tests for derived atoms
- [ ] No ESLint warnings or TypeScript errors
Contributor guide
Research direction
Start by reading apps/web/lib/store.ts and checking the repository’s existing TypeScript, React, and test conventions. Create the four files under apps/web/atoms with the specified user, theme, settings, and re-export responsibilities, then add tests for derived atoms, persistence, updates, and edge cases. Done means the listed files, tests, linting, and type checks pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100