npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

planeso-google-sync

v0.4.0

Published

Sync your Plane.so work items with a Google calendar

Readme

Plane.so Google Sync

This is a simple script to sync your Plane.so work items with Google Calendar. It uses the work items' due dates (and optionally start dates) to create and maintain all-day events in your Google Calendar.

It is meant to run locally on your machine, updating every run. You can set it up as a cron job or a scheduled task to run at regular intervals.

Installation

npm install planeso-google-sync -g

Setup

1. Google Calendar credentials

  1. Go to the Google Cloud Console and create or select a project.
  2. Enable the Google Calendar API for the project.
  3. Create an OAuth 2.0 Client ID (application type: Desktop app) and download credentials.json.
  4. Open the downloaded file and copy its contents into your config file (see below).

2. Plane.so API token

  1. Open your Plane.so workspace and go to Profile → API tokens.
  2. Create a new token and copy it.

3. Find your Plane.so project ID

You need the UUID of the specific project you want to sync. You can find it in the project's URL or settings inside Plane.so.

4. Create a config file

Create a file called planeso-google-sync.config.yml in whatever directory you will run the command from (or pass --config <path> to point to it elsewhere).

sync:
  - plane:
      apiKey: your-plane-api-token
      workspace: your-workspace-slug   # the slug, not the UUID
      projectId: your-project-uuid

    google:
      calendarId: primary              # or a specific calendar ID
      auth:
        clientId: "YOUR_CLIENT_ID.apps.googleusercontent.com"
        projectId: "your-project-id"
        authUri: "https://accounts.google.com/o/oauth2/auth"
        tokenUri: "https://oauth2.googleapis.com/token"
        authProviderX509CertUrl: "https://www.googleapis.com/oauth2/v1/certs"
        clientSecret: "YOUR_CLIENT_SECRET"
        redirectUris:
          - "http://localhost:8080"

The google.auth block is the installed object from the credentials.json file downloaded in step 1 (note the keys are camelCase here, not snake_case as they appear in the downloaded file).

The redirectUris entry must match one of the redirect URIs configured in the Google Cloud Console. For a Desktop app, http://localhost:PORT is recommended — the tool starts a local webserver on that port to capture the OAuth callback automatically.

5. First run

On the first run the tool will open your browser and ask you to grant calendar access. After you approve, the browser redirects to localhost and the tool captures the authorization code automatically. The OAuth token is saved to ~/.config/planeso-google-sync/<clientId>.token.json so subsequent runs happen silently.

Usage

planeso-google-sync

By default the tool looks for planeso-google-sync.config.yml in the current directory. Use --config to specify a different path:

planeso-google-sync --config /path/to/my-config.yml

Options

| Option | Default | Description | |---|---|---| | --config <path> | planeso-google-sync.config.yml | Path to the YAML config file |

How it works

Each run fetches all work items in the configured Plane.so project and syncs those that have a due date to Google Calendar as all-day events:

  • New item (no matching calendar event yet) → creates a new all-day event.
  • Changed item (title or dates differ) → updates the existing event.
  • Removed/date-cleared item (event exists but item no longer qualifies) → deletes the orphaned event.

If a work item also has a start date, the calendar event spans from start date to due date. Otherwise it is a single-day event on the due date.

Events are tagged with a private extended property so the tool only touches what it created and never interferes with your other calendar entries.

Each event description includes a link back to the work item in Plane.so.

Run it as a cron job or scheduled task to keep your calendar continuously in sync. For example, to update every 15 minutes with cron:

*/15 * * * * cd /path/to/config && planeso-google-sync

Full config reference

sync:                                  # list of sync configs; you can have multiple
  - plane:
      apiKey: your-plane-api-token     # required
      workspace: your-workspace-slug   # required
      projectId: your-project-uuid     # required
      baseUrl: https://api.plane.so    # optional; set for self-hosted Plane instances

    google:
      calendarId: primary              # required
      syncDescriptions: false          # optional; copy work item description into the event
      singleDayPrefix: ""              # optional; prepended to the title for single-day events
      multiDayPrefix: ""               # optional; prepended to the title for multi-day events
      stateSuffixes:                   # optional; appended to the title based on work item state
        completed: " ✓"
        cancelled: " ✗"
      auth:
        clientId: "..."                # required
        projectId: "..."               # required
        authUri: "..."                 # required
        tokenUri: "..."                # required
        authProviderX509CertUrl: "..." # required
        clientSecret: "..."            # required
        redirectUris:                  # required; first entry is used
          - "http://localhost:8080"
        localPort: 8080                # optional; override the port the local callback server listens on
        tokenFile: ""                  # optional; override where the OAuth token is stored

    sync:
      states:                          # optional; set a state group to false to exclude those items
        backlog: true
        unstarted: true
        started: true
        completed: true
        cancelled: true
        triage: true