- Notebin: A decentralized code snippet sharing platform using Nostr protocol (NIP-C0 implementation)
- Built with Next.js 15, React 19, TypeScript, and Tailwind CSS
- Uses shadcn/ui components and Radix UI primitives
- Feature-based structure: Components organized in
src/features/by domain (editor, login, navigation, post, snippet-feed, zap) - Barrel exports: Each feature exports components via
index.tsfiles - State management: Zustand store in
src/store/index.tswith localStorage persistence - Path aliases: Uses
~/forsrc/directory
- Nostr integration: Uses
nostr-toolsfor decentralized functionality - Authentication: NextAuth with custom Nostr credentials provider
- Code editor: CodeMirror with language extensions and themes
- Data fetching: TanStack Query for server state
- Styling: Tailwind CSS with
cn()utility function combining clsx and tailwind-merge - Icons: Lucide React icons
- Avatars: Dicebear for generated avatars
npm run dev # Development server with Turbopack
npm run build # Production build
npm run start # Production server
npm run lint # Next.js linting (also runs Biome)- Linting/Formatting: Biome (configured in
biome.json) - TypeScript: Strict mode enabled with path mapping
- Component conventions:
- "use client" directive for client components
- Custom hooks prefixed with
use - Feature components exported via barrel files
- shadcn/ui Components: Before implementing features that may require new UI components, check if additional shadcn/ui components are needed and ask the user to install them first. Do not attempt to create missing components yourself.
- Global state:
src/store/index.ts - Types:
src/types/index.ts - Utilities:
src/lib/utils.ts - Constants:
src/lib/constants.ts - Auth config:
src/auth/index.ts - Nostr utilities:
src/lib/nostr/
- Purpose: Batch management library for deduplicating and batching requests within a time window
- Installation:
npm install @yornaath/batshit - Key Features:
- Automatically groups similar data requests to reduce API calls
- Configurable schedulers (time-based, size-based, or hybrid)
- Custom resolvers for complex data mapping
- Basic Usage:
import { create, keyResolver, windowScheduler } from "@yornaath/batshit"; const users = create({ fetcher: async (ids: number[]) => { return client.users.where({ userId_in: ids }); }, resolver: keyResolver("id"), scheduler: windowScheduler(10), // 10ms time window }); // These requests will be batched if called within 10ms const user1 = await users.fetch(1); const user2 = await users.fetch(2);
- Best Practices:
- Create batchers once, outside of component renders
- Use memoization for context-specific batchers
- Consider
windowedFiniteBatchScheduler()for size + time constraints
- Documentation: https://github.com/yornaath/batshit
- Next.js: https://nextjs.org/docs
- React: https://react.dev/reference/react
- Tailwind CSS: https://tailwindcss.com/docs
- shadcn/ui: https://ui.shadcn.com/docs
- Radix UI: https://www.radix-ui.com/primitives/docs/overview/introduction
- Zustand: https://zustand.docs.pmnd.rs/
- TanStack Query: https://tanstack.com/query/latest/docs/framework/react/overview
- NextAuth.js: https://next-auth.js.org/getting-started/introduction
- CodeMirror: https://codemirror.net/docs/
- nostr-tools: https://github.com/nbd-wtf/nostr-tools
- Nostr NIPs: https://github.com/nostr-protocol/nips
- Nostr Protocol: https://nostr.com/
- NIP-C0 Spec: https://github.com/nostr-protocol/nips/blob/master/C0.md
- Lucide Icons: https://lucide.dev/icons/
- Dicebear: https://www.dicebear.com/styles
- Biome: https://biomejs.dev/