|
|
Log in / Subscribe / Register

Old-school calendaring at the command line with Remind

By Joe Brockmeier
August 25, 2026

Remind is a command-line calendar and alarm program, with an optional Tk-based graphical interface, for Linux and Unix-like operating systems. It has its own scripting language that allows users to create reminders that are difficult (if not impossible) to specify in other calendaring programs. It is wholly unsuitable for use in corporate environments that require calendar sharing and exchanging meeting invitations; however, it may be precisely the calendaring tool for users who prefer the command line and fast, flexible tools that can help keep track of messy schedules.

Mesozoic calendaring

According to The Book of Remind by Remind's author, Dianne Skoll, the first version was created in late 1989: "the Mesozoic era of computing". In 1990, she gained access to Usenet and decided to release the source code for Remind on comp.sources.misc for all to enjoy. Skoll has had what she calls an "unhealthy obsession with calendar software" that has led her to keep working on Remind ever since, except for a short break from 2005 to 2007.

Remind is actually a collection of several programs released under the GPLv2: the main remind command-line utility, the TkRemind (tkremind) graphical front-end, and helper utilities such as Rem2HTML and Rem2PDF that create printable calendars from Remind output. All of the applications are written in C with minimal dependencies. TkRemind requires Tcl/Tk and the standard Tcl library (tcllib). The Rem2HTML and Rem2PDF utilities require a couple of Perl modules.

The project is, essentially, a one-person show; according to the Git history, which includes pre-Git commits back to 1996, Skoll has accepted only 13 commits from other authors. The official repository is hosted on a Forgejo instance (a username and password, both "notabot", are required due to AI scrapers), with mirrors on Codeberg and Debian's Salsa.

Remind is available in the package repositories of most major Linux distributions, though Arch Linux's package is missing the tcllib dependency needed for TkRemind. Users who want to use TkRemind, Rem2HTML, or Rem2PDF on Arch will need to look to the Arch User Repository (AUR) or compile directly from source.

Remind scripts

As befits a utility from the Mesozoic, remind reads a text file containing a reminders script and sends reminders to standard output. The name of the file is unimportant, but TkRemind defaults to ~/.reminders, so that is the convention that I use. Remind uses a date-specification language that is fairly intuitive for simple events, but also allows users to set reminders that would be out of the question for desktop calendar applications like Evolution or Thunderbird Calendar.

When remind is run, it evaluates the script according to the current time and issues reminders that match a command's trigger date (see the trigger computation section of the man page for more on that). Here is a simple example that will set a reminder to send a TPS report to the boss every Friday, and a reminder that displays on August 21 about dinner plans.

    REM Friday MSG Send Mr. Spacely the weekly TPS report.
    REM 21 Aug 2026 AT 17:00 MSG Dinner at Blue Mountain Pizza in %1.

This is mostly self-explanatory: a reminder command begins with REM, and some expression of when it should occur. Remind has other types of commands, some of which we'll cover shortly. The next part of the command is the date specification. A day of the week, without any other information, will cause remind to issue a reminder every week on that day. A specific date, like "21 Aug 2026" will issue a reminder just on that day. Note that Remind is reasonably liberal in what it accepts as date input—it interprets "Aug 21", "21 Aug", "August 21 2026", and "2026-08-26" as the same date if run on August 21, 2026. Obviously, if one is specifying dates far enough in the future, it is a good idea to include the year as a matter of habit.

The text that follows MSG is the message that will be displayed. The "%1" in this example is a substitution filter that will be replaced with a countdown from "now"; that is, the message will contain a specific countdown of when the event will occur from the moment that Remind is run. The output from the example above would look something like this:

    $ remind .reminders
    Reminders for Friday, 21st August, 2026 (today):

    Send Mr. Spacely the weekly TPS report.

    Dinner at Blue Mountain Pizza in 6 hours and 41 minutes from now.

Of course, if Friday is a holiday or vacation day, then it will be necessary to send the TPS report earlier, later, or skip it entirely. Remind makes it possible to account for this with the OMIT command coupled with keywords such as AFTER, BEFORE, and SKIP. For instance, this example indicates that the TPS report should be skipped if it lands on a date that has been omitted, such as December 25—which just happens to land on a Friday this year.

    OMIT 25 December
    REM Friday SKIP MSG Send Mr. Spacely the weekly TPS report.

Note that a standalone OMIT command is considered globally; that is, it is considered for all REM entries with a SKIP keyword.

Remind can do more than emit messages; for instance, its RUN command can be used to run shell commands as well. This entry would run a backup script ("~/bin/backup.sh") every Friday, but only once:

    REM Friday ONCE RUN ~/bin/backup.sh

Note that Remind checks the last access date of the reminder script (e.g. "~/.reminders") to determine the last time it was run. That means that if a user edits the file later in the day, Remind will assume it hasn't been run that day. Using remind -r will avoid re-running any RUN commands.

Remind is intended as a calendaring program that reminds users about events, and is not designed as a task manager. It does, however, have a TODO keyword that can be used to provide a reminder of a task on the day it's due as well as before (and after) its due date. For example:

    REM TODO ++7 COMPLETE-THROUGH 24 Aug 2026 MAX-OVERDUE 3 MSG Big report due %b.

The "++7" tells Remind to start triggering the reminder seven days before the due date here. Note that "++7" will include omitted dates; to exclude omitted dates, use a single plus sign (e.g. "+7") instead. That entry will trigger a reminder for seven days prior to the due date and three days after. If the MAX-OVERDUE bit is not included, then it will trigger the reminder every day after the task is due until the entry is deleted. The %b is replaced with the actual number of days between the current date and the reminder's trigger date.

Many times it's desirable to have an event that recurs regularly until a certain date. For example, maybe there is an art class that meets outdoors and runs on Thursdays from June to September. Remind has an UNTIL keyword that allows the user to add that to their reminders until the last day of the class, like so:

    REM Jun 3 2026 *7 UNTIL Sep 1 2026 MSG Art class in the park.

These examples only scratch the surface of the Remind language and syntax. Like other programming languages, Remind's has variables, data types, operators, as well as built-in and user-defined functions. For instance, it has built-in functions for Easter, Hebrew calendar dates, the moon's phases, sunrise, sunset, and more. Adding the example below, taken from the Remind wiki (requires the "notabot" username and password), will show the sunrise and sunset times each day:

    SET $LongDeg 71
    SET $LongMin 10
    SET $LongSec 30
    SET $LatDeg 42
    SET $LatMin 20
    SET $LatSec 27
    MSG Sunrise at [sunrise(trigdate())], Sunset at [sunset(trigdate())], \
    next full moon at [moontime(2)] on [moondate(2)]%

Saved as moon.rem that example would produce output something like this:

    $ remind moon.rem
    Reminders for Friday, 21st August, 2026 (today):

    Sunrise at 06:53, Sunset at 20:10, next full moon at 00:19 on 2026-08-28

The script sets the variables for the user's location, which are used by the built-in functions to calculate the times for the next sunrise, sunset, and full moon. The trigdate() function returns the computed trigger date—in this case, August 21.

The Remind language is covered comprehensively in the remind man page and there are a number of examples in Skoll's book. Suffice it to say that it is easy to create reminders for the simple one-off and recurring events, as well as being possible to handle events that have exceptions due to holidays, are triggered by other events, or happen only once in a blue moon.

Remind has a few different modes of operation; agenda mode is the standard mode of operation. It runs the Remind script and prints the reminders that are triggered for that time and day. Users may also wish to generate a calendar to see a whole month at a time: remind -c filename will display a calendar in the terminal using ASCII characters, while the -cu option will display the calendar using Unicode box-drawing characters which look a little nicer.

It is also possible to generate a calendar that covers an arbitrary number of weeks by adding the +N option, where "N" equals the number of weeks. For example, remind -c+2 filename will display a two-week calendar. Remind can also produce JSON output using the -ppp option, which may be desirable if a user wants a standard format to use with another program. For example, users can run remind -ppp filename | rem2pdf > calendar.PDF, which will pipe JSON output to rem2pdf for conversion to a PDF calendar.

Look for the helpers

Remind is probably a program that will appeal most to people who enjoy working at the command line and editing plain-text files. However, TkRemind does provide a usable graphical interface for those who prefer the point-and-click method. The "Add Reminder..." feature, shown below, lets users create reminders with a fair amount of flexibility.

[TkRemind interface]

Users don't need to choose between the command-line utility and TkRemind, but entries created with TkRemind should not be edited manually. TkRemind adds a TAG entry to the reminders it creates to indicate that they should not be edited in other programs to avoid unpredictable results. The TAG keyword is used to add additional information to a reminder; when remind is run with a -p option, that tag is passed to the helper program (such as TkRemind) which can make use of the information. Otherwise, remind does not act on information in a TAG.

Over the years, there have been a number of third-party "helper" programs written to work with Remind as well, some of which are listed on the project's web site. This includes various scripts to convert Remind output to iCalendar format (or vice versa), tools to synchronize Remind with a CalDAV server, an Emacs major mode (remind-calendar.el), a web-based frontend written in PHP, and more.

In addition to Skoll's book and the remind man page there is also a remind-fans mailing list for users to discuss the use of Remind and ask questions, and a #remind IRC channel on the Open and Free Technology Community (OFTC) network. Remind is, perhaps, not for everyone, but it has its appeal for users who prefer flexibility and expressiveness over convenience.



The LWN site is currently under high scraper load, so comment display has been suppressed for anonymous users. If you are a human, you may read the comments by clicking the button below:

Note: you can avoid this step in the future by logging into your LWN account.


Copyright © 2026, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds