* feat: Calendar app for NIP-52 date-based and time-based events Adds a Calendar app with a polished month grid as the default view: today/selected-day highlighting, adjacent-month days, per-day event pills capped with a "+N more" indicator, and a day agenda panel with an ordered event list. Supports combinable filters (event type, author, free-text search) with a visible active-filter count and per-filter clearing, keyboard navigation (arrows/Home/End/PageUp/ PageDown) with roving tabindex, loading skeletons, empty/error states, and a NIP-19 share link for each event. naddr links for kind 31922/31923 now open the Calendar app instead of the Reader. Time-based events (kind 31923) are queried with a relay-side `#D` day-granularity filter; date-based events (kind 31922) have no indexable date field in NIP-52, so they're bounded by `limit` and filtered client-side against the viewed range — documented in useCalendarEvents.ts. Spike decision: built a custom month grid instead of using the existing react-day-picker wrapper or a new calendar library. react-day-picker is built for single/range date selection, not dense per-cell event content or multi-day spanning; a full calendar library would add real weight and its own theming to reconcile with shadcn. A CSS-grid month view is the smallest solution that meets the month-grid, filtering, and accessibility requirements with zero new dependencies. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BYiUtZMQeA5RHggQw73wto * fix: address Copilot review — keyboard trap, midnight formatting, nprofile hint - MonthGrid: exactly one gridcell must stay tab-focusable. When no day is selected and the displayed month doesn't contain today (e.g. after a PageUp/PageDown jump), every cell previously got tabIndex=-1, trapping keyboard users out of the grid. Falls back to the 1st of the month. - calendarEvents: formatEventTimeRange treated `end` as inclusive when checking same-day, so a time-based event ending exactly at local midnight formatted as a cross-day range even though eventDateKeys() attributes it to the start day only. Now compares against end-1ms, consistent with eventDateKeys(). - CalendarFilters: the author placeholder/error text only mentioned npub/hex even though nprofile is accepted (resolveAuthorInput handles it) — updated both to mention all three. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BYiUtZMQeA5RHggQw73wto * fix: address second Copilot review round on Calendar app - MonthGrid: focusKey preferred selectedDate even when it fell outside the currently rendered grid (selectedDate survives month navigation so the agenda keeps showing it, so after Prev/Next/PageUp/PageDown it commonly points at a day no longer on screen) — every cell got tabIndex=-1 again, reopening the keyboard trap fixed last round. Now only trusted when it's actually one of the rendered cells. - MonthGrid: the weekday header row sat as a sibling before the role="grid" element instead of inside it, so assistive tech couldn't associate the columnheaders with the grid. Grid role now wraps both the header row and the week rows. - MonthGrid: the loading skeleton always rendered 35 cells (5 weeks) even for 6-week months, causing a layout jump once the real 42-cell grid replaced it. Now sized from the same buildWeeks() count used for the real grid. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BYiUtZMQeA5RHggQw73wto * fix: guard arrow-key navigation against out-of-grid dates in MonthGrid Co-authored-by: mroxso <24775431+mroxso@users.noreply.github.com> --------- Co-authored-by: highperfocused <highperfocused@pm.me> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
MKStack
The Complete Framework for Building Nostr Clients with AI
MKStack is an AI-powered framework for building Nostr applications with React 18.x, TailwindCSS 3.x, Vite, shadcn/ui, and Nostrify. Build powerful Nostr applications with AI-first development - from social feeds to private messaging, MKStack provides everything you need to create decentralized apps on the Nostr protocol.
🚀 Quick Start
Build your Nostr app in 3 simple steps:
1. Install & Create
npm install -g @getstacks/stacks
stacks mkstack
2. Build with AI
stacks agent
# Tell Dork AI what you want: "Build a group chat application"
3. Deploy Instantly
npm run deploy
# ✅ App deployed to NostrDeploy.com!
✨ What Makes MKStack Special
- 🤖 AI-First Development: Build complete Nostr apps with just one prompt using Dork AI agent
- ⚡ 8 Minutes Average: From idea to deployed application in minutes, not months
- 🔗 50+ NIPs Supported: Comprehensive Nostr protocol implementation
- 🎨 Beautiful UI: 48+ shadcn/ui components with light/dark theme support
- 🔐 Built-in Security: NIP-07 browser signing, NIP-44 encryption, event validation
- 💰 Payments Ready: Lightning zaps (NIP-57), Cashu wallets (NIP-60), Wallet Connect (NIP-47)
- 📱 Production Ready: TypeScript, testing, deployment, and responsive design included
🛠 Technology Stack
- React 18.x: Stable version with hooks, concurrent rendering, and improved performance
- TailwindCSS 3.x: Utility-first CSS framework for styling
- Vite: Fast build tool and development server
- shadcn/ui: 48+ unstyled, accessible UI components built with Radix UI
- Nostrify: Nostr protocol framework for Deno and web
- React Router: Client-side routing with BrowserRouter
- TanStack Query: Data fetching, caching, and state management
- TypeScript: Type-safe JavaScript development
🎯 Real-World Examples
Built with One Prompt
Each of these applications was created with just a single prompt to Dork AI:
-
Group Chat Application:
"Build me a group chat application" -
Decentralized Goodreads:
"Build a decentralized goodreads alternative. Use OpenLibrary API for book data." -
Chess Game:
"Build a chess game with NIP 64"
Production Apps
Real Nostr applications built using MKStack:
- Chorus: Facebook-style groups on Nostr with built-in eCash wallet
- Blobbi: Digital pet companions that live forever on the decentralized web
- Treasures: Decentralized geocaching adventure powered by Nostr
Browse more apps made with MKStack →
🔧 Core Features
Authentication & Users
LoginAreacomponent with account switchinguseCurrentUserhook for authentication stateuseAuthorhook for fetching user profiles- NIP-07 browser signing support
- Multi-account management
Nostr Protocol Support
- Social Features: User profiles (NIP-01), follow lists (NIP-02), reactions (NIP-25), reposts (NIP-18)
- Messaging: Private DMs (NIP-17), public chat (NIP-28), group chat (NIP-29), encryption (NIP-44)
- Payments: Lightning zaps (NIP-57), Cashu wallets (NIP-60), Nutzaps (NIP-61), Wallet Connect (NIP-47)
- Content: Long-form articles (NIP-23), file metadata (NIP-94), live events (NIP-53), calendars (NIP-52)
Data Management
useNostrhook for querying and publishinguseNostrPublishhook with automatic client tagging- Event validation and filtering
- Infinite scroll with TanStack Query
- Multi-relay support
UI Components
- 48+ shadcn/ui components (buttons, forms, dialogs, etc.)
NoteContentcomponent for rich text renderingEditProfileFormfor profile managementRelaySelectorfor relay switchingCommentsSectionfor threaded discussions- Light/dark theme system
Media & Files
useUploadFilehook with Blossom server integration- NIP-94 compatible file metadata
- Image and video support
- File attachment to events
Advanced Features
- NIP-19 identifier routing (
npub1,note1,nevent1,naddr1) - Cryptographic operations (encryption/decryption)
- Lightning payments and zaps
- Real-time event subscriptions
- Responsive design with mobile support
🤖 AI Development with Dork
MKStack includes Dork, a built-in AI agent that understands your codebase and Nostr protocols:
Supported AI Providers
Configure your AI provider with stacks configure:
- OpenRouter (openrouter.ai): Enter your API key from settings
- Routstr (routstr.com): Use Cashu tokens for payment
- PayPerQ (ppq.ai): OpenAI-compatible API
How Dork Works
- Context-Aware: Understands your entire codebase and project structure
- Nostr Expert: Built-in knowledge of 50+ NIPs and best practices
- Instant Implementation: Makes changes directly to your code following React/TypeScript best practices
Example prompts:
"Add user profiles with avatars and bio"
"Implement NIP-17 private messaging"
"Add a dark mode toggle"
"Create a marketplace with NIP-15"
📁 Project Structure
src/
├── components/ # UI components
│ ├── ui/ # shadcn/ui components (48+ available)
│ ├── auth/ # Authentication components
│ └── comments/ # Comment system components
├── hooks/ # Custom React hooks
│ ├── useNostr # Core Nostr integration
│ ├── useAuthor # User profile data
│ ├── useCurrentUser # Authentication state
│ ├── useNostrPublish # Event publishing
│ ├── useUploadFile # File uploads
│ └── useZaps # Lightning payments
├── pages/ # Page components
├── lib/ # Utility functions
├── contexts/ # React context providers
└── test/ # Testing utilities
🎨 UI Components
MKStack includes 48+ shadcn/ui components:
Layout: Card, Separator, Sheet, Sidebar, ScrollArea, Resizable Navigation: Breadcrumb, NavigationMenu, Menubar, Tabs, Pagination Forms: Button, Input, Textarea, Select, Checkbox, RadioGroup, Switch, Slider Feedback: Alert, AlertDialog, Toast, Progress, Skeleton Overlay: Dialog, Popover, HoverCard, Tooltip, ContextMenu, DropdownMenu Data Display: Table, Avatar, Badge, Calendar, Chart, Carousel **And many more...
🔐 Security & Best Practices
- Never use
anytype: Always use proper TypeScript types - Event validation: Filter events through validator functions for custom kinds
- Efficient queries: Minimize separate queries to avoid rate limiting
- Proper error handling: Graceful handling of invalid NIP-19 identifiers
- Secure authentication: Use signer interface, never request private keys directly
📱 Responsive Design
- Mobile-first approach with Tailwind breakpoints
useIsMobilehook for responsive behavior- Touch-friendly interactions
- Optimized for all screen sizes
🧪 Testing
- Vitest with jsdom environment
- React Testing Library with jest-dom matchers
TestAppcomponent provides all necessary context providers- Mocked browser APIs (matchMedia, scrollTo, IntersectionObserver, ResizeObserver)
🚀 Deployment
Built-in deployment to NostrDeploy.com:
npm run deploy
Your app goes live instantly with:
- Automatic builds
- CDN distribution
- HTTPS support
- Custom domains available
📚 Documentation
For detailed documentation on building Nostr applications with MKStack:
🤝 Contributing
MKStack is open source and welcomes contributions. The framework is designed to be:
- Extensible: Easy to add new NIPs and features
- Maintainable: Clean architecture with TypeScript
- Testable: Comprehensive testing setup included
- Documented: Clear patterns and examples
📄 License
MKStack is dedicated to the public domain.
To the extent possible under law, the authors have waived all copyright and related or neighboring rights to MKStack. You are free to copy, modify, distribute, and use this software for any purpose, commercial or non-commercial, without asking permission and without attribution.
Build amazing Nostr applications and help grow the decentralized web!
"Vibed with MKStack" - Learn more about MKStack
Build your Nostr app in minutes, not months. Start with AI, deploy instantly.