Building a Real Notes CLI App with Rust — From Scratch to Exporting PDF

Rawan AlrajehRawan Alrajeh
3 min read

🧠 Why I Built This Project

As a software engineer diving deeper into Rust, I wanted more than tutorials — I needed something real. I chose to build a command-line app for managing notes: something useful, practical, and just complex enough to explore Rust's true power.

🚀 What This CLI App Does

This isn't your basic "Hello, world!" project. Here's what my Notes CLI tool can do:

  • Add structured notes with a title, body, and tags

  • Track created and updated timestamps

  • Search by tag or keyword

  • Export all notes to PDF, CSV, or Markdown

  • Automatically open the PDF after exporting

Everything runs in the terminal, powered by Rust and a clean modular codebase.

🦀 Rust Concepts I Practiced

I didn't just build an app — I learned the language:

struct and enum

Used for representing notes, user status, and CLI command types. Rust makes it easy (and fun) to model your data clearly.

clap

My CLI parser of choice. clap made it elegant to define arguments like --add-note, --export-pdf, or --search-tag.

serde + serde_json

These two made serializing notes into JSON a breeze — and loading them back just as easy.

chrono

For managing timestamps: when a note was created, and when it was last updated.

File I/O

Reading and writing .json, .csv, .md, and even generating .pdf — I used std::fs, OpenOptions, and Rust's amazing safety net to keep file operations solid.

🔥 Cool Features I’m Proud Of

  • --open-pdf — after export, the file opens automatically depending on your OS

  • Structured JSON notes with IDs, timestamps, and tags

  • --search-tag and --search let you filter notes in real time

  • Auto-generated PDFs with Arabic text support (using custom fonts)

💥 What Was Hard

PDF Generation with Arabic

Getting genpdf to work with Arabic fonts was tricky. The default fonts don’t support RTL languages, so I had to bundle in a proper font like Amiri and load it manually.

Ownership + Borrowing

I thought I understood ownership until I started passing structs around. It took some trial and error, and a lot of & vs &mutmoments, but I finally got it.

CLI Design

Making a CLI app feel "usable" and not like a bunch of flags glued together took some planning. Having --add-note, --search-tag, --export-pdf, and --delete-note as separate pathways made it easier to maintain and test.

📦 Libraries Used

🧾 Final Thoughts

This project taught me more about Rust than any tutorial could. It made abstract concepts real. Now, when I see impl, Result, match, or a lifetimed reference, I know what it means — and I know I’ve built something real with it.

If you’re learning Rust and want to make something useful, build a CLI tool. You’ll get hands-on with the core of the language and end up with a project that’s truly yours.

🔗 Check it out: github.com/RawanAlrajeh/user-cli-rust

Built with ❤️ by Rawan Alrajeh

0
Subscribe to my newsletter

Read articles from Rawan Alrajeh directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rawan Alrajeh
Rawan Alrajeh

Front-End Developer with a passion for building clean, responsive interfaces. I love challenging myself with new technologies and creating projects that blend creativity and structure. Always learning, always building.