<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: simonchai-tw</title>
    <description>The latest articles on DEV Community by simonchai-tw (@simonchaitw).</description>
    <link>https://dev.to/simonchaitw</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4113127%2F732a2e3e-660b-4b6d-b5e0-f4b6020e83d7.png</url>
      <title>DEV Community: simonchai-tw</title>
      <link>https://dev.to/simonchaitw</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/simonchaitw"/>
    <language>en</language>
    <item>
      <title>How to Sync Google Tasks with Microsoft To Do (Two-Way, Free, No Subscription)</title>
      <dc:creator>simonchai-tw</dc:creator>
      <pubDate>Sun, 18 Oct 2026 17:29:29 +0000</pubDate>
      <link>https://dev.to/simonchaitw/how-to-sync-google-tasks-with-microsoft-to-do-two-way-free-no-subscription-3iad</link>
      <guid>https://dev.to/simonchaitw/how-to-sync-google-tasks-with-microsoft-to-do-two-way-free-no-subscription-3iad</guid>
      <description>&lt;p&gt;There's no official sync between Google Tasks and Microsoft To Do. If your life spans both — Gmail and Google Calendar on one side, Outlook and Teams on the other — you've probably resorted to maintaining the same tasks in two places, or just letting one of them go stale.&lt;/p&gt;

&lt;p&gt;This guide shows you how to keep them in a seamless two-way loop: change something on either side, and it shows up on the other. Free, open-source, no subscription, and your task data never passes through a third-party server.&lt;/p&gt;

&lt;h2&gt;
  
  
  What gets synced
&lt;/h2&gt;

&lt;p&gt;Everything you'd expect from a real two-way sync:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Titles, notes, due dates (with time reminders)&lt;/li&gt;
&lt;li&gt;Completion status — check it off anywhere, it completes everywhere&lt;/li&gt;
&lt;li&gt;Lists, subtasks, moves between lists, and deletions&lt;/li&gt;
&lt;li&gt;Edit on either side; both sides stay identical&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sync runs automatically in the background every 10 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 3-step setup (Windows)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Download the installer&lt;/strong&gt; from the project website and run it — no terminal, no commands.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Follow the setup wizard.&lt;/strong&gt; It walks you through connecting Google Tasks and Microsoft To Do (personal Microsoft accounts take the easy path).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Done.&lt;/strong&gt; A sync panel shows status and settings any time you want to check.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. Your tasks start syncing in the background.&lt;/p&gt;

&lt;p&gt;Mac and Linux users: see the website for the command-line install.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this instead of a paid sync service
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free forever.&lt;/strong&gt; MIT-licensed open source. No subscription, no per-task pricing, no "pro" tier holding your data hostage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private by design.&lt;/strong&gt; It runs entirely inside your own Google Apps Script project. No third-party server ever sees your task lists.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It doesn't guess.&lt;/strong&gt; When the two sides disagree ambiguously, the sync parks the conflict for your review instead of silently overwriting. Deletions take two rounds to confirm, so a misclick doesn't nuke your list.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Good to know
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Capacity:&lt;/strong&gt; comfortably handles around 300 task pairs; stress-tested to 600.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microsoft account type:&lt;/strong&gt; the wizard's easy path works with personal Microsoft accounts. Work or school accounts use the self-managed Entra setup in the deployment guide.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; $0. It runs on Google's free Apps Script quota.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Website &amp;amp; download: &lt;a href="https://simonchai-tw.github.io/tasks-todo-sync/" rel="noopener noreferrer"&gt;https://simonchai-tw.github.io/tasks-todo-sync/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Source code (GitHub, MIT): &lt;a href="https://github.com/simonchai-tw/tasks-todo-sync" rel="noopener noreferrer"&gt;https://github.com/simonchai-tw/tasks-todo-sync&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Disclosure: I'm the author of this tool. It's my own open-source project, and this post is a how-to, not an ad — the code is public and you can inspect everything it does.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>opensource</category>
      <category>tutorial</category>
      <category>googleappsscript</category>
    </item>
    <item>
      <title>Google Tasks ↔ Microsoft To Do, two-way sync: self-hosted</title>
      <dc:creator>simonchai-tw</dc:creator>
      <pubDate>Fri, 16 Oct 2026 10:25:34 +0000</pubDate>
      <link>https://dev.to/simonchaitw/google-tasks-microsoft-to-do-two-way-sync-self-hosted-4f07</link>
      <guid>https://dev.to/simonchaitw/google-tasks-microsoft-to-do-two-way-sync-self-hosted-4f07</guid>
      <description>&lt;h1&gt;
  
  
  A two-way sync engine that refuses to guess: fail-closed design for Google Tasks ↔ Microsoft To Do
&lt;/h1&gt;

&lt;p&gt;tasks-todo-sync is a self-hosted, two-way sync between Google Tasks and Microsoft To Do, running in your own Google Apps Script project. v1.0.0, 549 tests passing, Windows one-click installer. No third-party server ever sees your task list — because there isn't one.&lt;/p&gt;

&lt;p&gt;Two-way sync is a harder problem than it looks. Either side can change, edits can arrive out of order, and one API can be down while the other keeps accepting writes. The engine is built around one rule: when in doubt, stop — never guess.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fail-closed writes
&lt;/h2&gt;

&lt;p&gt;If a create's outcome is uncertain, the engine records it and halts instead of retrying blindly. A missed task is recoverable; a duplicated one corrupts everything downstream. Correlation markers track ambiguous creates so nothing is written twice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two-round deletion
&lt;/h2&gt;

&lt;p&gt;Nothing is removed on a single observation. The first round records the disappearance; the second round revalidates against the live API before anything is retired. Deletion evidence is journaled, so an interrupted round resumes cleanly instead of leaving orphans.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checksummed state with restore
&lt;/h2&gt;

&lt;p&gt;Sync state carries checksums with previous-generation restore. A broken round can't poison the next one — the engine falls back to the last known-good state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Time Bridge
&lt;/h2&gt;

&lt;p&gt;Google Tasks stores dates only, no time-of-day. The engine treats [TTS-TIME:HH:mm] markers in notes as the canonical time record: it sets the Microsoft due time and reminder, then splices the marker out. Optional Calendar projection renders timed tasks as 30-minute events on a dedicated secondary calendar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recurrence stays with its owner
&lt;/h2&gt;

&lt;p&gt;A Microsoft recurring series still syncs — it gets a plain Google counterpart, marked so the pair survives Microsoft's daily regeneration. What the engine never does is write into the recurrence itself: due and completion writes to a Microsoft-native recurring task are dropped, the time bridge leaves it alone, and it is never deleted — each of those once made Microsoft's engine re-anchor the series and duplicate tasks across rounds. If a task carries recurrence on both sides, the engine keeps its hands off and emails you to keep recurrence on one side only. Google-born recurring tasks sync as plain tasks — the engine implements no recurrence of its own and translates no rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built for the Apps Script budget
&lt;/h2&gt;

&lt;p&gt;The whole engine runs on a 10-minute trigger inside ~6 minutes of Apps Script execution budget. Everything is checkpointed and resumable, so a round that runs out of time picks up where it left off.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verified, not just written
&lt;/h2&gt;

&lt;p&gt;v1.0.0 went through a five-axis adversarial review: state machines, fuzzing, concurrency, mutation testing, static consistency. Every finding had to reproduce against shipped code; every fix ships with a regression test.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/simonchai-tw/tasks-todo-sync" rel="noopener noreferrer"&gt;https://github.com/simonchai-tw/tasks-todo-sync&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're running it, I'm collecting real-world data points: how many task pairs are you syncing, and which side do you edit more — Google or Microsoft? Answers here or on GitHub Issues genuinely shape what I build next.&lt;/p&gt;

</description>
      <category>api</category>
      <category>opensource</category>
      <category>productivity</category>
      <category>tools</category>
    </item>
    <item>
      <title>How I built bidirectional Google Tasks ↔ Microsoft To Do sync on Apps Script</title>
      <dc:creator>simonchai-tw</dc:creator>
      <pubDate>Mon, 07 Sep 2026 05:09:47 +0000</pubDate>
      <link>https://dev.to/simonchaitw/how-i-built-bidirectional-google-tasks-microsoft-to-do-sync-on-apps-script-1ago</link>
      <guid>https://dev.to/simonchaitw/how-i-built-bidirectional-google-tasks-microsoft-to-do-sync-on-apps-script-1ago</guid>
      <description>&lt;h1&gt;
  
  
  How I built bidirectional Google Tasks ↔ Microsoft To Do sync on Apps Script
&lt;/h1&gt;

&lt;p&gt;I wanted a small, self-hosted bridge between Google Tasks and Microsoft To Do—not another productivity dashboard or a service that keeps my data forever.&lt;/p&gt;

&lt;p&gt;The result is &lt;a href="https://github.com/simonchai-tw/tasks-todo-sync" rel="noopener noreferrer"&gt;tasks-todo-sync&lt;/a&gt;, an open-source Google Apps Script project that keeps both task systems moving in both directions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why state sync instead of Zapier?
&lt;/h2&gt;

&lt;p&gt;Manual copying is easy for a day and frustrating for a month. Zapier is great when one event causes one action, but bidirectional sync is different: either side can change, events can arrive out of order, and a task can be edited while the other system is unavailable. Triggers, filters, and deduplication rules become hard to reason about.&lt;/p&gt;

&lt;p&gt;The script reads both sides, maps task identities and fields, compares the latest known state, and applies necessary creates, updates, or completions. Stored state gives the sync a memory instead of blindly copying every item on every run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Apps Script?
&lt;/h2&gt;

&lt;p&gt;Apps Script runs on a schedule without managing a server; OAuth and project configuration stay with the automation; the code is approachable JavaScript; and logs make API problems inspectable. The trade-off is that you configure credentials and APIs yourself. This is intentionally self-hosted.&lt;/p&gt;

&lt;h2&gt;
  
  
  MIT, with honest limits
&lt;/h2&gt;

&lt;p&gt;The project is released under the MIT license. It is not a promise of perfect conflict resolution: API quotas, token expiry, renamed or deleted lists, transient failures, and provider-specific fields are real constraints. Back up important data and test with a small task set first.&lt;/p&gt;

&lt;p&gt;If this is useful, a &lt;a href="https://github.com/simonchai-tw/tasks-todo-sync" rel="noopener noreferrer"&gt;soft star on GitHub&lt;/a&gt; helps others find it. Feedback is welcome: &lt;a href="https://github.com/simonchai-tw/tasks-todo-sync" rel="noopener noreferrer"&gt;repo and setup notes&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>productivity</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
