2025-04-16 22:33:21 -05:00
# Project Overview
This project is a Nostr client application built with React 19.x, TailwindCSS 3.x, Vite, shadcn/ui, and Nostrify.
## Technology Stack
- **React 19**: Latest version of React with improved performance and features
- **TailwindCSS 3.x**: Utility-first CSS framework for styling
- **Vite**: Fast build tool and development server
- **shadcn/ui**: Unstyled, accessible UI components built with Radix UI and Tailwind
- **Nostrify**: Nostr protocol framework for Deno and web
- **React Router**: For client-side routing
- **TanStack Query**: For data fetching, caching, and state management
- **TypeScript**: For type-safe JavaScript development
## Project Structure
- `/src/components/` : UI components including NostrProvider for Nostr integration
- `/src/hooks/` : Custom hooks including `useNostr` and `useNostrQuery`
- `/src/pages/` : Page components used by React Router
- `/src/lib/` : Utility functions and shared logic
- `/public/` : Static assets
## Nostr Protocol Integration
2025-04-17 11:23:46 -05:00
This project comes with custom hooks for querying and publishing events on the Nostr network.
2025-04-16 22:33:21 -05:00
2025-04-17 11:23:46 -05:00
### The `useNostr` Hook
2025-04-16 22:33:21 -05:00
2025-04-17 11:23:46 -05:00
The `useNostr` hook returns an object containing a `nostr` property, with `.query()` and `.event()` methods for querying and publishing Nostr events respectively.
2025-04-16 22:33:21 -05:00
```typescript
2025-04-17 11:23:46 -05:00
import { useNostr } from '@nostrify/react ';
function useCustomHook() {
const { nostr } = useNostr();
// ...
}
2025-04-16 22:33:21 -05:00
```
2025-04-17 11:23:46 -05:00
### Query Nostr Data with `useNostr` and Tanstack Query
When querying Nostr, the best practice is to create custom hooks that combine `useNostr` and `useQuery` to get the required data.
2025-04-16 22:33:21 -05:00
```typescript
import { useNostr } from '@nostrify/react ';
import { useQuery } from '@tanstack/query ';
function usePosts() {
const { nostr } = useNostr();
return useQuery({
queryKey: ['posts'],
queryFn: async () => {
const events = await nostr.query([{ kinds: [1], limit: 20 }]);
return events; // these events could be transformed into another format
},
});
}
```
2025-04-17 11:23:46 -05:00
The data may be transformed into a more appropriate format if needed, and multiple calls to `nostr.query()` may be made in a single queryFn.
### The `useNostrPublish` Hook
To publish events, use the `useNostrPublish` hook in this project.
```tsx
import { useState } from 'react';
import { useCurrentUser } from "@/hooks/useCurrentUser ";
import { useNostrPublish } from '@/hooks/useNostrPublish ';
export function MyComponent() {
const [ data, setData] = useState< Record < string , string > >({});
const { user } = useCurrentUser();
const { mutate: createEvent } = useNostrPublish();
const handleSubmit = () => {
createEvent({ kind: 1, content: data.content });
};
if (!user) {
return < span > You must be logged in to use this form.< / span > ;
}
return (
< form onSubmit = {handleSubmit} disabled = {!user} >
{/* ...some input fields */}
< / form >
);
}
```
The `useCurrentUser` hook should be used to ensure that the user is logged in before they are able to publish Nostr events.
2025-04-16 22:33:21 -05:00
## Development Practices
- Uses React Query for data fetching and caching
- Follows shadcn/ui component patterns
- Implements Path Aliases with `@/` prefix for cleaner imports
- Uses Vite for fast development and production builds
- Component-based architecture with React hooks
- Default connection to multiple Nostr relays for network redundancy
## Build & Deployment
- Build for production: `npm run build`
- Development build: `npm run build:dev`
## Testing Your Changes
Use `npm run build` to check for build errors.