Explore infinite universes of communities, conversations, and connections on the decentralized web
Universes is a modern Nostr client that brings Discord-like community features to the decentralized Nostr protocol. Built with React, TypeScript, and cutting-edge web technologies, it offers a rich social experience with chat, marketplace, resources, and more.
- Create and join communities with organized channels
- Discord-like interface with familiar UX patterns
- Real-time messaging and conversations
- Thread support for organized discussions
- Real-time messaging with typing indicators
- Message reactions and emoji support
- File uploads via Blossom servers
- Message threading and replies
- Pinned messages
- Context menus for message actions
- Buy and sell items with Bitcoin/Lightning
- Community-specific marketplaces
- Secure peer-to-peer transactions
- Rich product listings with media
- Organize and share valuable content
- Folder-based resource management
- Community resource libraries
- Link sharing and previews
- User profiles with rich metadata
- Friend systems and social connections
- Direct messaging with NIP-44 encryption
- User status indicators
- Notification center
- Comprehensive moderation tools
- Admin panels and permissions
- Content reporting system
- Bulk moderation actions
- Auto-moderation settings
- Moderation logs and analytics
- NIP-44 encrypted direct messages
- Multiple account support
- Secure key management
- Privacy-focused design
- Beautiful dark/light theme system
- Responsive design for all devices
- Smooth animations and transitions
- Accessible components with Radix UI
- Professional Discord-inspired interface
- Node.js 18+
- npm or yarn
- A Nostr identity (created automatically if needed)
-
Clone the repository
git clone <repository-url> cd universes
-
Install dependencies
npm install
-
Start development server
npm run dev
-
Open your browser Navigate to
http://localhost:5173
npm run build
npm test
- React 18 - Modern React with hooks and concurrent features
- TypeScript - Type-safe JavaScript development
- Vite - Fast build tool and development server
- TailwindCSS 3 - Utility-first CSS framework
- shadcn/ui - Beautiful, accessible components built on Radix UI
- Radix UI - Low-level UI primitives for accessibility
- Lucide React - Beautiful icon library
- Nostrify - Modern Nostr framework for web applications
- nostr-tools - Core Nostr protocol utilities
- NIP-44 - Encrypted direct messaging
- NIP-19 - Bech32-encoded identifiers
- TanStack Query - Powerful data fetching and caching
- React Context - Global app state management
- Local Storage - Persistent user preferences
- ESLint - Code linting and quality
- Vitest - Fast unit testing
- Testing Library - Component testing utilities
src/
βββ components/ # Reusable UI components
β βββ auth/ # Authentication components
β βββ chat/ # Chat and messaging
β βββ comments/ # Comment system
β βββ community/ # Community management
β βββ dm/ # Direct messaging
β βββ layout/ # Layout components
β βββ moderation/ # Moderation tools
β βββ spaces/ # Marketplace & resources
β βββ ui/ # shadcn/ui components
βββ hooks/ # Custom React hooks
βββ pages/ # Page components
βββ lib/ # Utility functions
βββ contexts/ # React contexts
βββ test/ # Testing utilities
The app connects to Nostr relays for data. Default relay is wss://relay.nostr.band
, but users can switch between preset relays:
- Nostr.Band - General purpose relay
- Damus - Popular iOS client relay
- Primal - Caching relay with web client
- Ditto - Community-focused relay
Built-in light/dark theme support with system preference detection:
import { useTheme } from '@/hooks/useTheme';
const { theme, setTheme } = useTheme();
setTheme('dark' | 'light' | 'system');
No environment variables required for basic functionality. The app works out-of-the-box with default Nostr relays.
import { useNostrPublish } from '@/hooks/useNostrPublish';
const { mutate: createEvent } = useNostrPublish();
// Create a community (NIP-72)
createEvent({
kind: 34550,
content: JSON.stringify({
name: "My Community",
about: "A place for awesome discussions",
picture: "https://example.com/image.jpg"
}),
tags: [
['d', 'my-community-id'],
['name', 'My Community'],
['about', 'A place for awesome discussions']
]
});
import { useNostrPublish } from '@/hooks/useNostrPublish';
const { mutate: createEvent } = useNostrPublish();
// Send a chat message (NIP-28)
createEvent({
kind: 42,
content: "Hello, community!",
tags: [
['e', 'community-event-id', '', 'root'],
['p', 'recipient-pubkey']
]
});
import { useNostr } from '@nostrify/react';
import { useQuery } from '@tanstack/react-query';
function useMessages(communityId: string) {
const { nostr } = useNostr();
return useQuery({
queryKey: ['messages', communityId],
queryFn: async ({ signal }) => {
const events = await nostr.query([{
kinds: [42],
'#e': [communityId],
limit: 50
}], { signal });
return events;
}
});
}
- NIP-01 - Basic protocol flow
- NIP-02 - Contact lists and petnames
- NIP-04 - Encrypted direct messages (legacy)
- NIP-05 - DNS-based verification
- NIP-07 - Browser extension signing
- NIP-10 - Text note references and threading
- NIP-19 - Bech32-encoded identifiers
- NIP-22 - Comment threads
- NIP-28 - Public chat channels
- NIP-44 - Encrypted direct messages (modern)
- NIP-57 - Lightning zaps
- NIP-72 - Moderated communities
- NIP-94 - File metadata
The app may use custom event kinds for specific features. See NIP.md
(if present) for documentation of any custom protocol extensions.
The project includes comprehensive testing setup:
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage
import { render, screen } from '@testing-library/react';
import { TestApp } from '@/test/TestApp';
import { MyComponent } from './MyComponent';
test('renders correctly', () => {
render(
<TestApp>
<MyComponent />
</TestApp>
);
expect(screen.getByText('Expected text')).toBeInTheDocument();
});
npm run build
# Deploy dist/ folder to your hosting provider
npm run deploy
Uses nostr-deploy-cli
to deploy directly to Nostr relays.
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature
- Commit changes:
git commit -m 'Add amazing feature'
- Push to branch:
git push origin feature/amazing-feature
- Open a Pull Request
- Follow TypeScript best practices
- Use existing hooks and components when possible
- Write tests for new features
- Follow the established code style
- Update documentation for new features
This project is open source. See the LICENSE file for details.
- Nostr Protocol - Decentralized social networking protocol
- shadcn/ui - Beautiful component library
- Nostrify - Modern Nostr framework
- MKStack - Development framework
Vibed with MKStack β‘
- Documentation: Check the
/src
folder for detailed component documentation - Issues: Report bugs and feature requests via GitHub Issues
- Community: Join Nostr communities to connect with other users
- Protocol: Learn more about Nostr at nostr.com
Explore infinite universes of communities, conversations, and connections on the decentralized web. π