Skip to content

markusweimer/gtd

Repository files navigation

GTD - Getting Things Done App

A cross-platform Getting Things Done (GTD) app built with React Native, TypeScript, and Expo. All data is stored in JSON Lines (JSONL) format for maximum portability, sync capability, and crash safety.

Development Approach

The entire code, including the README.md files outside of this section, is AI generated. This is an experiment of mine to see how far I can get with AI tools. The code is specifically written in TypeScript because I have no prior experience in that language or ecosystem. It goes without saying that I do not recommend anyone to use this for any real scenario at this time.

Tools used:

  • Claude Code
  • GitHub Copilot (various models)

I switch tools when I run out of tokens on one. I switch models in Copilot for the same reason.

Features

  • JSON Lines Storage: Append-only JSONL format for data safety
  • Cross-Platform: Runs on iOS, macOS, Linux, and web
  • GTD Methodology: Follows David Allen's Getting Things Done system
  • Hierarchical Tasks: Tasks can have subtasks (project breakdown)
  • Multiple Contexts: Assign tasks to multiple contexts (@home, @computer, etc.)
  • File-based Routing: Modern navigation with Expo Router
  • TypeScript: Fully typed for better development experience
  • Comprehensive Tests: 60+ unit tests with Vitest
  • ESLint + Prettier: Code quality and formatting

Tech Stack

  • React Native 0.81 - Latest React Native version
  • React 19.1 - Latest React version
  • TypeScript 5.9 - Static typing with strict mode
  • Expo 54 - Development and build tooling
  • Expo Router 6 - File-based navigation (like Next.js)
  • Expo File System - Local file storage for JSONL database
  • Vitest 4 - Fast unit testing framework
  • JSON Lines - Append-only data format

Project Structure

gtd/
├── app/                        # Expo Router file-based routing
│   ├── _layout.tsx            # Root layout
│   ├── index.tsx              # Root redirect to tabs
│   └── (tabs)/                # Tab navigation
│       ├── _layout.tsx        # Tabs layout
│       ├── index.tsx          # Inbox screen
│       ├── tasks.tsx          # All tasks (projects & actions)
│       └── more.tsx           # More options screen
├── src/
│   ├── types/                 # TypeScript type definitions
│   │   ├── gtd.ts            # GTD domain types & helpers
│   │   └── gtd.test.ts       # Type helper tests
│   ├── services/              # Business logic services
│   │   ├── jsonlStorage.ts   # JSON Lines storage
│   │   └── jsonlStorage.test.ts # Storage tests
│   └── constants/             # App constants
│       └── storage.ts         # Storage configuration
├── assets/                    # Images, fonts, etc.
├── eslint.config.js          # ESLint 9 flat config
├── vitest.config.ts          # Vitest configuration
├── tsconfig.json             # TypeScript configuration
└── package.json              # Dependencies and scripts

Data Storage: JSON Lines (JSONL)

All GTD data is stored in a single JSON Lines file for simplicity and safety:

gtd/
├── README.md               # System overview
├── gtd.jsonl              # Main database (all tasks & contexts)
├── backups/               # Automatic backups
│   └── gtd-YYYYMMDD.jsonl
├── reference/             # Supporting information
└── reviews/               # Weekly review notes

JSON Lines Format

Each line in gtd.jsonl is a complete JSON object representing one entity:

{"type":"task","id":"task-1","title":"Write README","parentId":null,"contexts":["@computer"],"tags":["docs"],"status":"active"}
{"type":"task","id":"task-2","title":"Buy groceries","parentId":"__INBOX__","contexts":[],"tags":[],"status":"active"}
{"type":"context","id":"@computer","name":"Computer","icon":"💻"}
{"type":"context","id":"@home","name":"Home","icon":"🏠"}

Data Model

Task (GTDTask):

{
  id: string;              // Unique identifier
  title: string;           // Task title
  description?: string;    // Optional details
  parentId?: string;       // Parent task ID (null = root, __INBOX__ = inbox)
  contexts: string[];      // Context IDs (e.g., ["@computer", "@home"])
  tags?: string[];         // Optional tags
  status: "active" | "completed" | "on_hold" | "cancelled";
}

Context (GTDContext):

{
  id: string;      // Context ID (e.g., "@computer")
  name: string;    // Display name
  icon?: string;   // Optional emoji icon
}

Append-Only Design

  • New entities: Append new line
  • Updates: Append new version (old kept for history)
  • Deletes: Append tombstone marker (empty title)
  • Compaction: Automatically removes old versions when file > 10MB

Benefits:

  • ✅ Crash-safe (atomic appends)
  • ✅ Built-in version history
  • ✅ Easy to sync across devices
  • ✅ Simple conflict resolution
  • ✅ Works with standard Unix tools (grep, jq)

Getting Started

Prerequisites

  • Node.js 18+ installed
  • npm or yarn
  • iOS Simulator (for macOS) or Android Emulator
  • Expo Go app (for testing on physical devices)

Installation

# Install dependencies
npm install

# Start the development server
npm start

Running on Different Platforms

# iOS (macOS only)
npm run ios

# Android
npm run android

# Web (for testing)
npm run web

Development Scripts

# Type checking
npm run type-check

# Testing
npm test              # Run tests in watch mode
npm run test:run      # Run tests once (CI mode)
npm run test:ui       # Open visual test UI
npm run test:coverage # Generate coverage report

# Linting
npm run lint
npm run lint:fix

# Formatting
npm run format
npm run format:check

GTD Workflow

This app implements the five steps of GTD:

  1. Capture - Add items to your inbox
  2. Clarify - Process inbox items (coming soon)
  3. Organize - Move items to appropriate lists (coming soon)
  4. Reflect - Weekly review (coming soon)
  5. Engage - Do your next actions (coming soon)

Current Features

✅ Implemented

  • Data Model: Hierarchical tasks with multiple contexts
  • Storage: JSON Lines format with append-only writes
  • Inbox: Capture and view inbox items
  • Tasks: Unified view of projects and actions
  • Type System: Comprehensive TypeScript types with helper functions
  • Testing: 60+ unit tests covering core functionality
  • Navigation: Tab-based navigation with Expo Router
  • Auto-compaction: Database optimization when > 10MB

🚧 Coming Soon

  • Context-based task filtering
  • Task editing and completion
  • Project breakdown UI
  • Search and filtering
  • Weekly Review
  • Quick capture widget
  • File sync configuration
  • Dark mode

Learning Resources

TypeScript

React Native

GTD Methodology

File Sync

The JSONL database file can be synced across devices using:

  • iCloud Drive - Built-in on Apple devices
  • Syncthing - Open source, cross-platform sync
  • Git - Version control (excellent for append-only format)
  • Dropbox/Google Drive - Cloud storage

Sync-Friendly Design:

  • Single file reduces sync conflicts
  • Append-only format works well with file-based sync
  • Automatic compaction keeps file size manageable
  • Text format works with all sync tools
  • Built-in version history via append-only writes

Recommended: Use Git for best version control and conflict resolution.

Contributing

This is a personal learning project, but contributions and suggestions are welcome!

License

MIT License - feel free to use this code for your own projects.

Acknowledgments

  • David Allen for the GTD methodology
  • Expo team for excellent React Native tooling
  • React Native community

About

AI-developed Getting Things Done (GTD) implementation

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors