The missing piece of your Google Calendar.
Goaly automatically finds free time in your existing Google Calendar and natively schedules recurring goals (like reading, working out, or meditating) based on your personal time preferences, duration, and frequency.
- Smart Google Calendar Integration: Automatically fetches your busy events and schedules your goals into empty gaps.
- Time Preferences: Set your preferred time of day (Morning, Afternoon, Evening, Night) for each individual goal.
- Customizable: Choose from a wide variety of UnoCSS icons and native Google Calendar colors for each goal.
- Privacy-First & Self-Hosted: Powered by Deno, Astro, and SQLite. Your refresh tokens and data never leave your server.
- Deno installed (used for both server and package management)
- A Google Cloud Project with the Google Calendar API enabled
- An OAuth 2.0 Client ID and Secret (Web Application type, redirect URI:
http://localhost:8080/api/auth/callback)
- Clone the repository to your local machine.
- Copy the environment template and fill in your Google credentials:
cp .env.example .env
- Open
.envand fill in the details:GOOGLE_CLIENT_ID=your_client_id_here GOOGLE_CLIENT_SECRET=your_client_secret_here PUBLIC_URL=http://localhost:8080
- Build the Astro project:
deno install --allow-scripts deno task build
- Start the Deno server:
deno run -A dist/server/entry.mjs
- Open
http://localhost:8080in your browser.
-
Build the container using the provided
Containerfile:docker build -t goaly -f Containerfile . # or podman build -t goaly -f Containerfile .
-
Run the container, providing the required environment variables:
GOOGLE_CLIENT_ID: Your Google OAuth 2.0 Client ID.GOOGLE_CLIENT_SECRET: Your Google OAuth 2.0 Client Secret.PUBLIC_URL: The public URL where your instance is accessible (e.g.,http://localhost:8080).DB_PATH: The path to the SQLite database file inside the container. It defaults togoaly.dbin the current working directory, but should be set to a path inside a mounted volume for persistence (e.g.,/data/goaly.db).
Example
docker runcommand:docker run -d \ -p 8080:8080 \ -e GOOGLE_CLIENT_ID=your_client_id_here \ -e GOOGLE_CLIENT_SECRET=your_client_secret_here \ -e PUBLIC_URL=http://localhost:8080 \ -e DB_PATH=/data/goaly.db \ -v $(pwd)/data:/data \ --name goaly \ goaly
This project uses Deno for package management and tooling. After making any code changes, always run the following commands to format your code, catch linting errors, and verify the build:
deno run cithis runs, lint, fmt --check, check (typecheck) & tests
Goaly is actively being developed. Here is a look at what's coming next:
- Gotify Reminders: Implement proactive notifications via Gotify to remind users of upcoming goals.
For more details on upcoming features and technical specifications, check out our ROADMAP.md.
- Frontend: Astro (SSR), UnoCSS
- Backend: Deno custom server
- Database: SQLite (
node:sqlite) - Authentication: Google OAuth 2.0 (Offline token access)
- Primary color: #005F6A
- Accent: #FFBF00
- Background: #FFFFFF
- Main text: #1f2937
- Muted text: #6b7280
Built with the help of OpenCode and Pi using many LLMs and also Claude Code.
This project is licensed under the MIT License - see the LICENSE file for details.