Noteworthy is a sleek and efficient note-taking web application.
Powered by Next.js and Rust, it offers users a simple yet powerful platform to organise their thoughts, ideas, and tasks.
- Frontend Framework: Next.js
- Styling: Tailwind CSS
- Language: TypeScript (Frontend) and Rust (Backend)
- Backend: Ink (Rust-based, using Axum)
- Database: PostgreSQL (self-hosted) with SQLx for database interactions
- Authentication: NextAuth (client-side) and Ink (server-side JWT-based authentication)
This now reflects the current state of your stack. Let me know if this works for you, and I'll include it in the PR!
A significant portion of Noteworthy's UI design is inspired by the Figma community file Nowted.
The backend for Noteworthy has been rewritten in Rust and is now served via a service called Ink, using the Axum framework.
- Axum: A web framework for building fast, reliable, and scalable APIs in Rust. It powers all API interactions in Noteworthy.
- SQLx: A safe, asynchronous SQL toolkit and ORM layer used to interact with the self-hosted PostgreSQL database.
- Authentication: JWT-based authentication is now handled in Rust using jsonwebtoken for token management and bcrypt for secure password hashing.
Forms across Noteworthy, including those for authentication and other user interactions, are validated using Zod on client-side, providing robust validation and ensuring data integrity.
Additionally, users' profile images are stored on Cloudflare R2, offering a secure and scalable solution for image storage.
- Enjoy a clean and user-friendly interface for an effortless note-taking experience.
- Utilise server components to render and hydrate components on the server, optimising performance, caching and reducing client-side bundle size.
- Create Note: Create a new note using pre-created colours and providing a name.
- Generate Notes: Users can generate notes directly from the quick actions in the search modal, leveraging the power of Glimmer, a Gleam-based microservice that uses LLMs to generate note placeholder content.
- Favourite/Unfavourite Note: Easily mark notes as favourites or remove them from favourites.
- Archive/Unarchive Note: Archive notes to keep your workspace clutter-free, and unarchive them when needed.
- Search Notes: Quickly find specific notes using the search functionality.
- Filter Notes: Filter notes by title alphabetically, by creation time (newest or oldest), or by update time (last update first), with the default filter being by update time.
Note
A note cannot be archived and favourited at the same time; it's either one or none.
- Word Definitions and Phonetics: Look up definitions and phonetic transcriptions of words.
- Word Pronunciation: Audio pronunciations to help users learn the correct pronunciation.
- Synonyms and Antonyms: View synonyms and antonyms to enhance vocabulary.
- Examples with Selected Words: Display example sentences using the selected word for context.
Authentication in Noteworthy is managed through a combination of NextAuth for the client-side and Ink for the server-side.
NextAuth powers the client-side authentication, offering support for multiple authentication providers, including:
- Credentials (Email and Password): Users can sign up and log in using their email and password. The "forgot password" feature allows users to reset their password securely.
- GitHub OAuth: Users can authenticate using their GitHub account.
- Google OAuth: Users can authenticate using their Google account.
Important
The authentication system is immutable, ensuring that users cannot log in with the same email using different authentication methods. For example, if a user signs up with Google OAuth, they cannot use email and password with the same email.
Ink handles all the authentication logic on the server side. This includes:
- JWT-based Authentication: Users are authenticated via JWT, which are issued upon successful login and used for subsequent requests to access protected resources.
- Token Verification: The backend verifies and manages JWTs for user sessions, controlling access to resources like notes or user information.
In summary, while NextAuth handles user session management and provider integrations on the client-side, Ink secures and verifies all authentication flows on the server-side using Rust's robust security capabilities.
The note editor functionality in Noteworthy is powered by Tiptap, a headless editor. Customized by me, it offers the following features:
- Text Style: Choose from heading levels (1 to 4) or paragraphs.
- Font Family: Select from 6 available fonts, including Garamond, Montserrat, Lobster, Didot, Merriweather, and Source Sans 3 (default).
- Font Size: Change the font size using pre-selected values, with the default set to 12px.
- Alignment: Align text to left, center, right, or justify, with the default alignment set to left.
- Text Formatting: Format text with options to bold, Italicise, underline, strike, highlight, superscript, or subscript.
Enhance your productivity with these keyboard shortcuts:
- Align left: Ctrl+Shift+L
- Align center: Ctrl+Shift+E
- Align right: Ctrl+Shift+R
- Justify: Ctrl+Shift+J
- Bold: Ctrl+B
- Italic: Ctrl+I
- Underline: Ctrl+U
- Strike: Ctrl+Shift+S
- Highlight: Ctrl+Shift+H
- Save note: Ctrl+S
To run Noteworthy locally, follow these steps:
-
Clone this repository to your local machine:
git clone https://github.com/RuanCampello/noteworthy.git cd noteworthy
-
Ensure Docker and Docker Compose are installed on your machine. If not, follow the installation instructions here and here.
-
Install the dependencies:
npm install
-
Build and start the services using Docker Compose:
docker-compose up --build # or docker compose up --build
-
Enjoy the Rust compilation time :D
-
Open your web browser and visit http://localhost:3000.
Important
OAuth and Password Reset: In the development environment, OAuth authentication and password reset mailer are disabled. OAuth requires GitHub and Google environment variables, which are not set in the Docker environment, so do Resend.
Noteworthy supports multiple languages, allowing users to switch between languages seamlessly.
- English 🇬🇧
- Portuguese (BR) 🇧🇷
You can switch the language of the application using the language selector available in settings. The language files are stored in the public/locales directory, and the translations are managed via cookies using next-intl.
Create a new folder in the public/locales directory with the language name in English (e.g. spanish, Dutch).
Add translation JSON files (translations.json) in the new folder with the necessary translations.
Update the locales.ts file at src/lib/next-inlt/locales.ts
to include the new language in the locales array.
Contributions are welcome! If you have any suggestions, bug reports, or feature requests, please open an issue or submit a pull request.
This project is licensed under the AGPL-3.0 License.