Drafts named MacStories 2025 App of the Year

Very honored and proud to have Drafts named as MacStories 2025 App of the Year!

Thanks to the Drafts community for all you do to help make the app better with your feedback, creativity, and willingness to share all the interesting things you do with Drafts.

18 Likes

Well deserved :raising_hands:t4::raising_hands:t4::raising_hands:t4:

Congratulations!! :bottle_with_popping_cork::balloon::tada::confetti_ball:

Congratulations.

Well deserved, indeed.

So very well deserved!

Drafts has amazed me for years and just today I made a very easy time tracking solution after ditching all other apps, services, text files, even creating an account and then deleting it. Why? It turned out Drafts could provide me with a very flexible and user friendly solution with only two actions: START and STOP, which

  1. creates a new draft for notes,
  2. log a timestamp, START, permalink, and tags, in another draft, Journal (thus linking back to the notes draft) or timestamp and STOP.

Mac, iPhone or Apple Watch doesn’t matter, just track your time with two actions that can easily be adapted to my current and future needs. I was especially happy to find that strftime is included in the JavaScript library.

Thank you Greg! You just made my day when I need to report my work to The European Social Fund.

All the best,

P-D

3 Likes

Just to add another voice to this. @agiletortoise it’s a modern cliche, but thank you for all you do.

I think this from MacStories is worth highlighting:

Drafts is the ultimate example of what it means to combine taste, solid design principles, and the ingenuity to accept how software is changing and how a single developer who’s been working on the same app for the past 13 years can still find new ways to innovate and explore the frontier of iOS automation.

Exactly right.

Also in modern parlance, thank you for not - as they say - “enshitifying” the app. It is noticed and appreciated.

1 Like

Please give an example of your usage…

With pleasure, Amelchi.

The workflow is still very much in progress but due to the endless possibilities of Drafts, it can easily be adapted and generalized to other use cases. Even though this is not a finished polished workflow, it seems to work well for me, without any other time tracking apps or subscriptions

It has two main actions START and STOP, and I am experimenting with some more logging facilities. Instead of saving data to a log file or a database, I found it easy to use a draft called Journal, with simple START and STOP lines, linking to a new draft for every work pass, so everything is contained in Drafts.

START goes like this (in my current version):

  1. Create a new draft, and
    1. set the syntax to Simple list,
    2. set the title to a timestamp s.a. 2025-12-22 00.28.36 (not necessary but to simplify)
    3. add (the context with all visble apps in progress and) a list with - { }
    4. add the actual project as a tag from a Configured Value (work in progress to improve but currently I have only one project, necessary to log).
  2. Log the timestamp START permalink to another draft called Journal (based on its permanent uuid) and update in the background.
  3. Present the newly created draft to the user (me :wink: for adding more information on what to do.

Here is the (uncommented) code in progress:

d = new Draft()

syntax = Syntax.find("builtIn", "Simple List")
d.syntax = syntax
permalink = d.permalink
myDate = d.createdAt
startDate = strftime(myDate,"%Y-%m-%d %H.%M.%S")

// Also, add a list of all visible apps to log what I am working on.
// In progress but the main AppleScript handler is this
// tell app "System Events" to return (name of processes whose visible is true) as text
//

d.content = startDate + "\n\n- { } "
d.addTag("log")
project = context.configuredValues["project"]
d.addTag(project)
d.update()
editor.load(d)

j = Draft.find("024B3A61-577E-48AF-A335-69CCE20BB03D")
j.append(startDate + "	START	" + permalink + "	" + d.tags)
j.update()

STOP simply writes a timestamp and STOP to the same Journal draft.

myDate = new Date()
stopDate = strftime(myDate,"%Y-%m-%d %H.%M.%S")

j = Draft.find("024B3A61-577E-48AF-A335-69CCE20BB03D")
j.append(stopDate + "	STOP")
j.update()

Recently I experimented with an action for adding the screen time with app- and website-usage to the the draft, later when the system has collected the data:

  1. Select a START and STOP line the Journal draft.
  2. Run the action Work – which in turn runs a shortcut which gets the start and end time for the screen time and returns it data.
  3. Write the usage (for that time interval) to the draft for that work.

The (uncommented) code in progress for this process is:

t = editor.getSelectedText()
shortcut = Shortcut.create("Work", t)
pattern = /drafts:\/\/open\?uuid=([A-F0-9-]+)/i

uuid = t.match(pattern)[1]
d = Draft.find(uuid)
editor.load(d)

shortcut = Shortcut.create("Work", t)
shortcut.run()
d.append(shortcut.result)
d.update()

My shortcut “Work” runs partly a shell script to get the start and end time (from the selection, matching strings for timestamps, and sorting for security reasons so second line will allways be later than the first line of the match):

printf "$1" | egrep -o '202[0-9]-[01][0-9]-[0-3][0-9] [0-2][0-9][:\.][0-5][0-9][:\.][0-5][0-9]' | sort

This yields two lines with the timestamp for the start and end of the screen time, requested, which are then assigned to two variables used in the action for screen time.

In addition to that I created a start and stop action as my iPhone widget for the locked screen and may even stop work on the project from my Apple Watch.

I am still amazed at how much I can do with Drafts and how well this now seems to serve me for 2026: “As simple as possible, but not simpler.”

The Journal draft will then look something like this:

2025-11-12 15.57.48	START	drafts://open?uuid=DBFA78FC-72E1-4718-8EF7-B6DA38E53426	puls
2025-11-12 16.59.51	STOP
2025-12-11 11.00.00	START	drafts://open?uuid=DBFA78FC-72E1-4718-8EF7-B6DA38E53426	puls
2025-12-12 04.00.00	STOP
2025-12-17 13.00.00	START	drafts://open?uuid=51524464-7BA2-4EB2-95BF-B76E3D47594F	log,puls
2025-12-17 16.59.51	STOP
2025-12-18 16.48.07	START	drafts://open?uuid=92591DFF-3A3C-4635-B02B-C90920266E21	log,puls
2025-12-18 18.40.00	STOP

Sorry for the long lines but I decided to keep the full permalinks to facilitate going back and forth in Draffts link mode. Just click the link and remind yourself of what you were working on or uppdate the linked draft with new information.

You may also note that some entries do not have the tag “log” which simply means they do not refer to these “ordinary log drafts” but rather to other types of drafts, worked on for the same project (“puls”) for flexibility. (E.g. I had done work before I developed this system and wanted to include ot in my Journal draft for accounting purposes.) BTW, I will now also include a link to this page in order to show how you helped me to document the process :wink:

I also incuded an Alfred workflow with a list filter to START and STOP utilising Draft’s URL scheme.

drafts://runAction?text=Dummy&action=START

drafts://runAction?text=Dummy&action=STOP

Congrats on the award! Drafts looks awesome, and it would be really helpful for me. I would like to be able to make it a central part of my workflow. Unfortunately, as a lawyer, the fact that Drafts does not support Advanced Data Protection for iCloud (with end-to-end encryption of data synced via CloudKit) means I can’t use Drafts for anything work related. I know @agiletortoise has said you were looking into adding Advanced Data Protection. Please prioritize adding ADP.