A self-hosted document editor focused on speed, simplicity, and a calming user experience.
Nusk is a minimalist markdown editor with file storage that prioritizes instant feedback and beautiful UX over complex features. Write in peace, save automatically, and focus on your words.
- Beautiful & Calming UI - Soft color palette, generous whitespace, and smooth transitions
- Instant Document Creation - Create new documents instantly with no loading states
- Auto-Save - Automatic saving 1 second after you stop typing
- Markdown Editor - Clean textarea-based editor with live preview toggle
- Full-Text Search - Search through all your documents quickly
- Keyboard Shortcuts - Efficient writing with keyboard-first design
- Self-Hosted - Your data stays on your server
- Simple Auth - JWT-based authentication for secure access
Frontend:
- SvelteKit with TypeScript
- Tailwind CSS for styling
- Vite for fast builds
- Marked.js for markdown rendering
Backend:
- FastAPI (Python)
- SQLite for metadata
- File system storage for markdown files
- JWT authentication with bcrypt
- Clone the repository:
git clone https://github.com/yourusername/nusk.git
cd nusk- Start the application:
docker-compose up -d- Open your browser and navigate to:
- Frontend: http://localhost:3000
- Backend API: http://localhost:8000
That's it! Create an account and start writing.
Quick Start (Recommended):
./dev.shThis script will automatically set up and start both backend and frontend servers.
Manual Setup:
Backend:
cd backend
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
uvicorn main:app --reload --port 8000Frontend:
cd frontend
npm install
npm run devThe frontend will be available at http://localhost:5173
Global:
Cmd/Ctrl + K- Open searchCmd/Ctrl + N- Create new document
Editor:
Cmd/Ctrl + S- Save document (though auto-save has you covered)Cmd/Ctrl + P- Toggle preview modeCmd/Ctrl + B- Bold selectionCmd/Ctrl + I- Italic selectionCmd/Ctrl + K- Insert link
Click the "New Document" button or press Cmd/Ctrl + N. Your cursor will be ready to type immediately in an untitled document.
Documents save automatically 1 second after you stop typing. You'll see a subtle "Saved" indicator when saving completes. No manual saving needed.
Press Cmd/Ctrl + K to open search. Type to search through document titles and content. Results appear instantly.
Toggle between edit and preview modes by clicking the "Preview" button or pressing Cmd/Ctrl + P. Preview renders your markdown in real-time.
nusk/
├── backend/ # FastAPI backend
│ ├── main.py # Main application & routes
│ ├── database.py # SQLAlchemy models
│ ├── auth.py # Authentication logic
│ ├── schemas.py # Pydantic schemas
│ └── requirements.txt
├── frontend/ # SvelteKit frontend
│ ├── src/
│ │ ├── routes/ # Pages
│ │ ├── lib/ # Components & utilities
│ │ └── app.css # Global styles
│ └── package.json
├── storage/ # Document storage (created on first run)
├── docker-compose.yml # Docker orchestration
└── README.md
Edit backend/auth.py to change:
SECRET_KEY- JWT secret (use environment variable in production)ACCESS_TOKEN_EXPIRE_MINUTES- Token expiration time
Edit frontend/vite.config.ts to change:
- API proxy settings
- Development port
- Update
docker-compose.ymlwith your configuration - Set proper environment variables
- Run
docker-compose up -d - Set up a reverse proxy (nginx/caddy) for HTTPS
For production, set these environment variables:
Backend:
SECRET_KEY- Strong random secret for JWTDATABASE_URL- SQLite database path (optional)
Frontend:
ORIGIN- Your domain (for CORS)
Documents are stored as markdown files in the /storage directory:
- Structure:
/storage/{user_id}/{document_id}.md - Metadata stored in SQLite database
- Backup the
storagefolder andnusk.dbfile regularly
If docker-compose build fails with npm network errors (ECONNRESET), try:
-
Increase npm timeout - Edit
frontend/Dockerfileand add beforeRUN npm ci:ENV NPM_CONFIG_FETCH_TIMEOUT=300000 ENV NPM_CONFIG_FETCH_RETRIES=5 ENV NPM_CONFIG_FETCH_RETRY_MINTIMEOUT=10000
-
Retry the build - Network issues are often transient:
docker-compose build --no-cache
-
Use local development instead - Run
./dev.shto start without Docker
If the frontend can't reach the backend:
- Ensure backend is running on port 8000
- Check CORS settings in
backend/main.py - Verify API_BASE in
frontend/src/lib/utils/config.ts
- Change the
SECRET_KEYin production - Use HTTPS in production
- Regular backups of storage and database
- Consider implementing rate limiting for production use
Current version focuses on core functionality. Future additions may include:
- DOCX import/export using Pandoc
- Document version history
- Document sharing and collaboration
- Mobile app
- Rich text formatting options
- Image uploads
MIT License - feel free to use and modify as you wish.
Contributions are welcome! Please feel free to submit a Pull Request.
For issues and questions, please open an issue on GitHub.
Built with calm and focus.