A professional, statically-typed Command Line Interface (CLI) application for managing tasks. Built entirely with native Node.js and TypeScript, this project features a modular architecture, robust error handling, and persistent local data storage.
- Strictly Typed: Full TypeScript implementation utilizing custom types and interfaces.
- Modular Architecture: Business logic, data layers, and routing are strictly separated for maintainability.
- Persistent Storage: Reads and writes to a local
data.jsonfile using Node's nativefsandpathmodules. - Zero Dependencies: Built without heavy external CLI frameworks (like Yargs or Commander) to demonstrate core Node.js routing and string parsing fundamentals.
ts-cli-task-manager/
├── data/
│ └── data.json # Local database (git-ignored)
├── functions/
│ ├── add.ts # Logic for creating tasks
│ ├── complete.ts # Logic for marking tasks as done
│ ├── delete.ts # Logic for deleting tasks
│ ├── list.ts # Logic for listing all tasks
│ └── listfilter.ts # Logic for filtering tasks by status
├── types.ts # TypeScript interfaces (Task, Status)
├── db.ts # Data layer: handles fs read/write operations
├── main.ts # Application entry point and CLI router
├── package.json
├── tsconfig.json
└── .gitignore
To run this project natively without pre-compiling, you need to use tsx (TypeScript Execute).
Install tsx globally on your machine:
npm install -g tsxRun the application through your terminal using the tsx main.ts command followed by your desired action.
Creates a new task and sets its status to pending.
tsx main.ts add "Learn TypeScript Architecture"Marks an existing task's status as done using its ID.
tsx main.ts complete 1Marks a task's status as deleted using its ID.
tsx main.ts delete 1View all tasks currently in the database in a formatted table.
tsx main.ts listView a filtered list of tasks by passing a specific status flag (pending, completed, or deleted).
tsx main.ts list --status=pending- Singleton Data Pattern: The
db.tsfile acts as a single source of truth, loading the JSON database into memory once and sharing it across all modular functions via Module Caching. - Temporal Dead Zone Prevention: File execution is strictly ordered to ensure database arrays are initialized into memory prior to the router firing.
- Type Narrowing & Guard Clauses: Extensive use of early returns and type validation to prevent
undefinedorNaNinputs from crashing the Node execution thread. - Explicit Imports: The application bypasses barrel files in favor of explicit, direct imports to maintain strict visibility of dependencies within the
main.tsrouter.