Tasks to iCal
Paste your todo.txt — due: dates, t: start dates, priorities, projects and contexts — and get back a standards-compliant .ics file of to-dos or calendar events. Nothing leaves your browser.
About this tool
A todo.txt file is a plain-text task list: one task per line, with due: deadlines,
t: start dates, (A)–(Z) priorities, +project tags and @context tags. Calendars
and task apps do not read it — they read iCalendar. This tool is the step between them.
Paste your list and it hands back a standards-compliant .ics document you can save and
import into Apple Reminders, Nextcloud Tasks, Thunderbird, Google Calendar, Outlook or
anything else that speaks iCalendar.
The conversion runs as WebAssembly inside this page, so your task list never leaves the
browser tab. The output is deterministic too: DTSTAMP is a fixed constant and the entry
IDs are derived from the tasks themselves, so the same list always produces the same bytes.
That keeps re-imports and version-controlled calendar files clean — importing twice updates
the same entries instead of duplicating them.
A worked example
Paste this, leave every option alone:
(A) Pay the hosting invoice +admin @office due:2026-08-25
Draft the quarterly report +work t:2026-08-20 due:2026-08-28
Buy milk @errands
You get back:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//gizza-ai//tasks-to-ical//EN
CALSCALE:GREGORIAN
BEGIN:VTODO
UID:[email protected]
DTSTAMP:19700101T000000Z
DUE;VALUE=DATE:20260825
SUMMARY:Pay the hosting invoice
DESCRIPTION:(A) Pay the hosting invoice +admin @office due:2026-08-25
CATEGORIES:admin,office
PRIORITY:1
STATUS:NEEDS-ACTION
END:VTODO
BEGIN:VTODO
UID:[email protected]
DTSTAMP:19700101T000000Z
DTSTART;VALUE=DATE:20260820
DUE;VALUE=DATE:20260828
SUMMARY:Draft the quarterly report
DESCRIPTION:Draft the quarterly report +work t:2026-08-20 due:2026-08-28
CATEGORIES:work
STATUS:NEEDS-ACTION
END:VTODO
END:VCALENDAR
Three things to notice. The (A) became PRIORITY:1 and the metadata came out of the
SUMMARY, while the untouched original line was kept in DESCRIPTION, so nothing you wrote
is lost. The t: date became DTSTART, so the second task shows a start as well as a
deadline. And "Buy milk" is missing — it carries no date, and the default export is dated
tasks only. Switch Which tasks to export to Everything to bring undated tasks along as
unscheduled to-dos.
What each line can say
xat the very start marks the task done. In todo.txt the next bare date is the completion date and the one after it is the creation date — both are read.(A)through(Z)set priority, and are accepted before or after the completion date, or as apri:Atag. They map onto the RFC 5545 numeric scale:(A)→PRIORITY:1,(B)→5, everything else →9. A task with no priority letter gets noPRIORITYline.due:2026-08-25is the deadline;t:2026-08-20is the start (threshold) date. Add a time for a timed entry:due:2026-08-25T14:30, seconds optional.+projectand@contextwords becomeCATEGORIES, deduplicated and kept in the order you wrote them.uid:orid:pins the entry's ID, which is what you want if you plan to re-import an evolving list into the same calendar.rec:andh:are recognised and taken out of the summary. Anything else shaped likekey:valueis left exactly where you put it, so aurl:or a custom tag survives.- Blank lines and lines starting with
#are skipped, so a commented, sectioned file works.
To-dos or events
To-do (VTODO) is the default and the more faithful mapping: each task keeps its DUE,
its STATUS (NEEDS-ACTION, or COMPLETED with PERCENT-COMPLETE:100), its COMPLETED
and CREATED dates and its priority. Task apps — Apple Reminders, Nextcloud Tasks,
Thunderbird — import these as real tasks you can tick off.
Event (VEVENT) exists because several calendar apps, Google Calendar among them, ignore
VTODO entirely. An event lands on the grid where you will actually see it. A whole-day task
runs from its t: date through its due: date; a timed one starts at its time and runs for
the event length you pick. Because an event must sit somewhere on the calendar, an undated
task cannot become one — it is reported by line number rather than quietly dropped.
Times, timezones and reminders
A date with no time (due:2026-08-25) is written as VALUE=DATE, which every client shows as
a whole day and no timezone touches. A date with a time is anchored by the How the times are
anchored choice. Floating writes 20260825T143000 with no zone marker, so 14:30 reads
as 14:30 on whatever clock the reader has — the right choice for a personal deadline list.
UTC treats what you typed as already being UTC and appends the Z, so each calendar
converts it into local time — the right choice for a list shared across countries. There is
no per-task timezone tag; convert the times before pasting if they are mixed.
The reminder slider attaches a VALARM with ACTION:DISPLAY and the task text as its
message, from 5 minutes up to a week ahead. Leave it at 0 for no reminder. On a to-do the
trigger is anchored to the DUE date with RELATED=END, which is what RFC 5545 specifies;
on an event it counts back from the start.
Limits and edge cases
- Up to 2000 tasks per run. Past that the conversion stops and tells you to split the list rather than writing a truncated file.
- The event length applies only to a timed
VEVENT; it accepts 1 to 1440 minutes (one day). Whole-day events and everyVTODOignore it. - The reminder lead time accepts 0 to 10080 minutes (one week).
rec:repeat tags are not expanded intoRRULEs. todo.txt'srec:1whas no vocabulary for counts, end dates or "every second Tuesday", so translating it would invent repeats you did not ask for. Expand the repeats into dated tasks first, then convert.- A line whose date will not parse, whose
t:falls after itsdue:, or which is nothing but metadata with no task text, is reported by its line number — the file is not written with a broken entry in it. - Commas, semicolons and backslashes are escaped as RFC 5545 requires, and lines longer than 75 octets are folded with a leading space on the continuation, so a long task imports intact instead of being cut short by a strict parser.
- Entry IDs come from a
uid:/id:tag when you set one. Without it the ID is built from the task text and its position, which stays stable as long as the list does.
FAQ
How do I get the .ics file into my calendar or task app?
Save the output with an .ics extension — the Download link next to the result does it for
you. In Google Calendar on the web, go to Settings → Import & export and pick the file;
Outlook uses File → Open & Export → Import/Export → Import an iCalendar (.ics) file; Apple
Calendar and Reminders import with File → Import; Thunderbird uses Events and Tasks → Import.
Import into a new, empty calendar the first time, so you can delete the whole thing in one
click if the mapping was not what you expected.
Should I export to-dos or events?
Export to-dos if the app you are importing into has a task list — Apple Reminders,
Nextcloud Tasks and Thunderbird all read VTODO, and it is the only option that keeps
completion status, percent-complete and priority. Export events if your calendar ignores
VTODO, which Google Calendar does: the deadlines then appear on the grid as all-day or
timed entries. If you are unsure, export both and import them into two separate calendars —
the conversion is free and nothing is uploaded either way.
Why did most of my tasks disappear?
The default keeps only tasks carrying a due: or t: tag, because a working todo.txt is
mostly someday items that would clutter a calendar. Switch Which tasks to export to
Everything and the undated ones come along as VTODO entries with no DUE, which task apps
file under unscheduled. If a task you expected is dated and still missing, check the tag
spelling: due:2026-08-25 with no space after the colon, and an ISO date — due: tomorrow
or due:25/08/2026 will be reported as unreadable rather than guessed at.
What happens to tasks I have already finished?
They export by default, which is how you archive finished work: a line beginning with x
becomes STATUS:COMPLETED with PERCENT-COMPLETE:100 and a COMPLETED date taken from the
first bare date after the x. That is genuinely useful in a task app — it shows the work as
done rather than pretending it was never there. Turn on Leave out tasks already marked done
with x to export only what is still outstanding.
Will my rec: repeating tasks repeat in the calendar?
No. A rec: tag is recognised and removed from the summary, but it is not turned into an
RRULE, and the entry appears once on its due: date. todo.txt's recurrence syntax simply
does not carry enough information — there is no way to say how many times, until when, or on
which weekdays — so any automatic translation would produce repeats you did not write. Expand
the repeats into individual dated tasks first, then paste the expanded list here. The original
line, rec: tag and all, is kept in each entry's DESCRIPTION.
My multi-day event ends a day late. Is that a bug?
No — look at the dates in the calendar rather than in the .ics text. iCalendar all-day ends
are exclusive, so an event running the 20th through the 22nd has to be written with DTEND
on the 23rd. That day is added for you, which means you should write the last day the task
actually runs in due:, not the day after it.
Is anything uploaded?
No. The conversion is a WebAssembly module running in this page, so your task list stays in the browser tab. Load the page, disconnect from the network, and it still works. The same conversion is available offline in the command-line tool if you would rather script it over a todo.txt file on disk.
Developer & Automation Access
Run it from the terminal
Same engine as this page, headless — via the gizza CLI:
gizza tool tasks-to-ical "(A) Pay the hosting invoice +admin @office due:2026-08-25
Draft the quarterly report +work t:2026-08-20 due:2026-08-28
x 2026-08-19 2026-08-01 File the tax return +admin due:2026-08-19"New to the CLI? Get gizza →
Open it by URL
Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:
https://gizza.ai/tools/tasks-to-ical/?tasks=%28A%29%20Pay%20the%20hosting%20invoice%20%2Badmin%20%40office%20due%3A2026-08-25%0ADraft%20the%20quarterly%20report%20%2Bwork%20t%3A2026-08-20%20due%3A2026-08-28%0Ax%202026-08-19%202026-08-01%20File%20the%20tax%20return%20%2Badmin%20due%3A2026-08-19&component=vtodo&include=dated&skip_completed=true&duration_minutes=60&reminder_minutes=0&timezone=floating&calendar_name=Work%20deadlinesMachine-readable descriptor: tool.json — title + parameters JSON Schema for agents.
