JXA Examples

A collection of Javascript for Automation (JXA) examples for reference and learning. All the code in this repository was run and tested on macOS 10.15.4 Catalina.

JXA is the Javascript implementation of AppleScript and it allows to script Apple's standard applications, such as Calendar, Reminders, and Music. It can also be used to control the UI. There aren't any recent books or tutorials on JXA so I hope this collection will make your learning a little easier. Other resources are linked at the bottom of the page.

Task Boxes Basic uses various snippets from the examples below to create a basic productivty tool.

Page Structure

Script names start with the App or the library name they are demonstrating. The exceptions are:

Unpredicatbles

I have not done enough testing determine whether the following are bugs or in JXA or I am using it incorrectly

List of JXA Example Scripts

Jump to Index.


Apple Ref Add Attendee to Event

Open in Editor: Jump to Index | Top



    var app = Application.currentApplication()
    var Calendar = Application("Calendar")

    var projectCalendars = Calendar.calendars.whose({name: "Project Calendar"})
    var projectCalendar = projectCalendars[0]
    var events = projectCalendar.events.whose({summary: "Important Meeting!"})
    var event = events[0]

    var attendee = Calendar.Attendee({email: "example@apple.com"})
    event.attendees.push(attendee)

    Calendar.reloadCalendars();
  

Apple Ref Mail

Open in Editor: Jump to Index | Top


    Mail = Application('Mail')

    Mail.name()

    Mail.name

    Mail.outgoingMessages[0]

    //Mail.accounts[0].mailboxes[8].messages[0]()
    //Mail.accounts[0].mailboxes[8]()

    Mail.activate() //bring Mail to foreground
    Mail.accounts['iCloud'].checkForNewMail()

    // show latest message in inbox
    var latestMsg = Mail.inbox.messages[0]
    Mail.open(latestMsg);
  

Apple Ref New Keynote

Open in Editor: Jump to Index | Top


    // Example Code on WWDC talk

    Keynote = Application("Keynote")

    Keynote.activate() //foreground

    //document class, make it a method, and add make verb at the end.
    //newDoc = Keynote.Document().make()

    //can create with properties set as record
    doc = Keynote.Document({
        documentTheme:Keynote.themes["Artisan"],
        width: 1024,
        height: 768,
        autoPlay: true,
        autoLoop: true,
        autoRestart:true,
        maximumIdleDuration:3
        }).make();
  

Apple Ref Reference Doc Examples

Open in Editor: Jump to Index | Top

  //Trying to implement Apple Example Code, but it doesn't work out of box.

    Mail = Application('Mail')
    TextEdit = Application('TextEdit')

    Mail.name


    para = TextEdit.Paragraph({}, 'Some text')
    TextEdit.documents[0].paragraphs.push(para);
  

Apple Ref UI Text Prompt

Open in Editor: Jump to Index | Top


    // Include Apple's UI elements
    var app = Application.currentApplication()
    app.includeStandardAdditions = true

    var response = app.displayDialog("What's your name?", {
        defaultAnswer: "",
        withIcon: "note",
        buttons: ["Cancel", "Continue"],
        defaultButton: "Continue"
    })
    // Result: {"buttonReturned":"Continue", "textReturned":"Jen"}
    app.displayDialog("Hello, " + (response.textReturned) + ".");
  

Apple Ref Write to File

Open in Editor: Jump to Index | Top


    var app = Application.currentApplication()
    app.includeStandardAdditions = true

    function writeTextToFile(text, file, overwriteExistingContent) {
        try {

            // Convert the file to a string
            var fileString = file.toString()

            // Open the file for writing
            var openedFile = app.openForAccess(Path(fileString), { writePermission: true })

            // Clear the file if content should be overwritten
            if (overwriteExistingContent) {
                app.setEof(openedFile, { to: 0 })
            }

            // Write the new content to the file
            app.write(text, { to: openedFile, startingAt: app.getEof(openedFile) })

            // Close the file
            app.closeAccess(openedFile)

            // Return a boolean indicating that writing was successful
            return true
        }
      catch(error){

            try {
                // Close the file
                app.closeAccess(file)
            }
            catch(error) {
                // Report the error is closing failed
                console.log(`Couldn't close file: ${error}`)
            }

            // Return a boolean indicating that writing was successful
            return false
        }
    };
  

Apple Ref standard applications

Open in Editor: Jump to Index | Top


    // Loads Apple's UI elements and others.
    app = Application.currentApplication()

    app.includeStandardAdditions = true

    app.say('Greetings')

    dialogResult = app.displayDialog('Please enter your name', {
        withTitle: 'Greetings',
        defaultAnswer: '',
        buttons: ["Goodbye", "Hello"],
        defaultButton: 2
    })

    if (dialogResult.buttonReturned == "Hello") {
        app.say('Hello ' + dialogResult.textReturned)
        } else {
        app.say('Goodbye' + dialogResult.textReturned);
  

AppleRef Create Calendar

Open in Editor: Jump to Index | Top


    // Creates a Calendar

    var Calendar = Application("Calendar")
    var calendarName = "Demo"
    var calendarDescription = "Demo Calendar"
    var newCalendar = Calendar.Calendar({name: calendarName, description: calendarDescription}).make()
    // Result: Application("Calendar").calendars.at(3);
  

AppleRef Create an Event tomorrow at 1500

Open in Editor: Jump to Index | Top


    var app = Application.currentApplication()
    app.includeStandardAdditions = true
    var Calendar = Application("Calendar")

    var eventStart = app.currentDate()
    eventStart = eventStart
    eventStart.setDate(eventStart.getDate() + 1)
    eventStart.setHours(15)
    eventStart.setMinutes(0)
    eventStart.setSeconds(0)
    var eventEnd = new Date(eventStart.getTime())
    eventEnd.setHours(16)

    var projectCalendars = Calendar.calendars.whose({name: "DEMO"})
    //Use the first result that matches name search
    var projectCalendar = projectCalendars[0]
    var event = Calendar.Event({summary: "Important Meeting!", startDate: eventStart, endDate: eventEnd})
    projectCalendar.events.push(event);
  

AppleRef Reveal an Event

Open in Editor: Jump to Index | Top


    ////Requires "Demo" calendar with events

    var Calendar = Application("Calendar")

    var projectCalendars = Calendar.calendars.whose({name: "Demo"})
    var projectCalendar = projectCalendars[0]
    var events = projectCalendar.events.whose({summary: "Important Meeting!"})
    var event = events[0]
    event.show();
  

AppleRef read file FAILS

Open in Editor: Jump to Index | Top

  var app = Application.currentApplication()
    app.includeStandardAdditions = true

    var file = app.chooseFile({
        ofType: "txt",
        withPrompt: "Please select a text file to read:"
    })

    readFile(file);
  

Calendar Count Number of Events

Open in Editor: Jump to Index | Top

  //How to count number of events in a library?

    // All calendars
    Application('Calendar').calendars.events.length

    //First Calendar in your List
    Application('Calendar').calendars[0].events.length;
  

Calendar Create 1 hour event starting now

Open in Editor: Jump to Index | Top


    // Sometimes on first run it fails with invalid index, but unable to repeat

    var app = Application.currentApplication()
    app.includeStandardAdditions = true

    ////Requires "Demo" calendar with events
    //Create new event starting now and ending in one hour

    //Set Calendar to be the Application Calendar
    var Calendar = Application('Calendar')

    //Set name of Calendar you are using
    var calendarUsed = "Demo";

    //use Demo as the used Calendar by searching for it.
    var projectCalendars = Calendar.calendars.whose({name: calendarUsed});
    //Use the first result that matches name search
    var projectCalendar = projectCalendars[0];

    //You need the time now as an object
    var timeNow = new Date();

    //inAnHour as well
    var inAnHour = new Date();

    //Create Date object one hour ago for search criteria
    inAnHour.setHours(timeNow.getHours()+1);


    //Create new event with values from pervious event and end time of timeNow
    newEvent=Calendar.Event({summary: "Demo Event", startDate: timeNow, endDate: inAnHour});


    //Fails with invalid index on first run.
    projectCalendar.events.push(newEvent);
  

Calendar Delete Event byId

Open in Editor: Jump to Index | Top


    ////Requires "Demo" calendar with events

    //Creates new Event with same startDate as current event and endDate as Now
    // Deletes the event it replaces


    // Add standard library for dialog boxes
    var app = Application.currentApplication()
    app.includeStandardAdditions = true

    //Set Calendar to be the Application Calendar
    var Calendar = Application('Calendar')

    //Set name of Calendar you are using
    var calendarUsed = "Demo";

    //use Demo as the used Calendar by searching for it.
    var projectCalendars = Calendar.calendars.whose({name: calendarUsed})
    //Use the first result that matches name search
    var projectCalendar = projectCalendars[0]



    var testEvents = projectCalendar.events.whose({ summary: "TEST"});

    //set recentEvent to be the first in the results of search.
    //TODO deal with more than one search result
    var testEvent = testEvents[0]

    eventId = testEvent.id()
    //Delete the event with the old end time.

    Calendar.delete(projectCalendar.events.byId(eventId));
  

Calendar Event Create and Add Event Elements

Open in Editor: Jump to Index | Top


    //Event elements can be added, properties cannot be changed
    ////Requires "Demo" calendar with events


    //Set Calendar to be the Application Calendar
    var Calendar = Application('Calendar')

    //use Demo as the used Calendar by searching for it.
    var projectCalendars = Calendar.calendars.whose({name: "Demo"})
    //Use the first result that matches name search
    var projectCalendar = projectCalendars[0]

    //new keyword makes Date object
    var timeNow = new Date()


    //Creation of a new event with same start and end time as the pulled event
    newEvent=Calendar.Event({summary: "TEST", startDate: timeNow, endDate: timeNow})
    // Push the event to the calendar
    projectCalendar.events.push(newEvent)

    //Choose which event I will edit. In this case first one. Could also be .last or array value []
    var event = projectCalendar.events.last()
    // attendee is made as a function. Class Event contains element attendeess, which is why I can add(push) attendees.
    var attendee = Calendar.Attendee({email: "example@apple.com"})
    event.attendees.push(attendee)

    event.attendees[0]();
    event.startDate();
    //new Event(myEvent)
    //projectCalendar.events.length;
  

Calendar Event Search

Open in Editor: Jump to Index | Top


    ////Requires "Demo" calendar with events


    var Calendar = Application('Calendar')
    // Create demoDays object, which is an array of events where summaries start with Blog
    var demoDays = Application('Calendar').calendars[12].events.whose({ summary: { _beginsWith: 'Demo' } })()
    //Result: [Application("Calendar").calendars.byId("3E7ADB20-0113-4FD7-B04B-2AA470B83380").events.byId("5D241B42-D0EF-4312-B99F-E1E38A2E09A0"), Application("Calendar").calendars.byId("3E7ADB20-0113-4FD7-B04B-2AA470B83380").events.byId("C6E3B842-AAB3-4E95-8106-918E1FCB1C4C")]


    //Number of events starting with Blog in the Demo Calendar
    demoDays.length
    //Result: 2

    // Summary of first event returned
    demoDays[0].summary()
    // Result: "Blog Apple launchd"

    // Date event started
    demoDays[0].startDate()
    // Result: Fri Jul 19 2019 08:50:00 GMT+0200 (CEST)
    // it is an "object"


    //Date in milliseconds
    Date.now()
    //Result: 1584451353422

    var timeNow = new Date()
    //new keyword makes Date object

    var oneHour = 60 * 60 * 1000;
    //Create Date object that is one hour ago timeNow.
    var anHourAgo = new Date(new Date() - oneHour);



    //https://stackoverflow.com/questions/38023712/comparisons-rich-queries-in-javascript-for-automation-jxa-whose
    var recentDemoEvents = Application('Calendar').calendars[12].events.whose({
        _and: [
            { startDate: { _greaterThan: anHourAgo }},
            { startDate: { _lessThan: timeNow}}
        ]
    });




    //Array of events that started in the past hour.
    recentDemoEvents();

    //Single event's summary that started in past hour from the Demo Calendar
    recentDemoEvents[0]().summary();
  

Calendar Find Events in past hour

Open in Editor: Jump to Index | Top


    //Find Event in past hour in specific calendar.
    //the events are not in order in the Calendar.events array, therefore you need specify time frames

    var Calendar = Application('Calendar')
    Calendar.reloadCalendars();

    //Use the Demo calendar
    usedCalendar=Application('Calendar').calendars[12]


    var timeNow = new Date()
    //new keyword makes Date object

    var oneHour = 60 * 60 * 1000;
    //Create Date object that is one hour ago timeNow.
    var anHourAgo = new Date(new Date() - oneHour);



    //https://stackoverflow.com/questions/38023712/comparisons-rich-queries-in-javascript-for-automation-jxa-whose
    var recentDemoEvents = Application('Calendar').calendars[12].events.whose({
        _and: [
            { startDate: { _greaterThan: anHourAgo }},
            { startDate: { _lessThan: timeNow}}
        ]
    });




    //Array of event functions that started in the past hour. The event function has properties that are objects.
    recentDemoEvents();

    //Single event that started in past hour
    typeof(recentDemoEvents[0]().endDate());

    recentDemoEvents[0]()
    //Result:Application("Calendar").calendars.byId("3E7ADB20-0113-4FD7-B04B-2AA470B83380").events.byId("A9154DCD-9E76-4383-8ABC-5062D578EE5E")

    var event = recentDemoEvents[0]();
    //You can create new objects by calling class constructors as functions
    event;
  

Calendar Get Number of Events in all

Open in Editor: Jump to Index | Top

  //Read the number of Events in a given calendar.

    Application('Calendar').calendars[0].events.length;
  

Calendar Open file Alarm exploration

Open in Editor: Jump to Index | Top


    //Looking at the Alarm poperty on an event
    // Requires an Automator calendar with even and alarm property.


    // Working with Application Calendar
    var Calendar = Application("Calendar")


    // Use specific calendar matching name
    var projectCalendars = Calendar.calendars.whose({name: "Automator"})


    //Use the first calendar that matches the name
    var projectCalendar = projectCalendars[0]()


    // Gets information for the last created element in calendar
    var eventinfo = projectCalendar.events.last()

    // Have a single object to return with all the information

    eventinfo.openFileAlarms();
    eventinfo.properties();
    projectCalendar.keys();
  

Calendar Read Upcoming Event into Array

Open in Editor: Jump to Index | Top


    //https://leancrew.com/all-this/
    //If "Example Event" and "Demo" calendar do not exist script fails

    var now = new(Date)

    var Calendar = Application("Calendar")
    var homeCal = Calendar.calendars.whose({name: "Demo"})[0]

    var swHomeEvents = homeCal.events.whose({
      _and: [
        {startDate: {_greaterThan: now}},
        {summary: {_beginsWith: "Example Event"}}
      ]
    })

    var swEvents = swHomeEvents()
    swEvents;
  

Calendar Read event information

Open in Editor: Jump to Index | Top


    //Requires "Demo" calendar with events

    // Working with Application Calendar
    var Calendar = Application("Calendar")


    // Use specific calendar matching name
    var projectCalendars = Calendar.calendars.whose({name: "Demo"})


    //Use the first calendar that matches the name
    var projectCalendar = projectCalendars[0]()


    // Gets information for the last created element in calendar
    var eventinfo = projectCalendar.events.last()

    eventinfo.properties();
  

Calendar Show an Event

Open in Editor: Jump to Index | Top


    //Shows Example Event in Calendar Demo.
    //If "Example Event" and "Demo" calendar do not exist script fails

    var Calendar = Application("Calendar")

    //Returns all Calendars with matching name
    var projectCalendars = Calendar.calendars.whose({name: "Demo"})

    //Only use the first one that matches name
    var projectCalendar = projectCalendars[0]

    //Same logic as with Calendar, returns all, you only want the first one.
    var events = projectCalendar.events.whose({summary: "Example Event"})
    var event = events[0]
    event.show();
  

Calendar Sort events by Date

Open in Editor: Jump to Index | Top


    //Set Calendar to be the Application Calendar
    var Calendar = Application('Calendar')

    //Set name of Calendar you are using
    var calendarUsed = "Demo"

    //use Demo as the used Calendar by searching for it.
    var projectCalendars = Calendar.calendars.whose({name: calendarUsed})
    //Use the first result that matches name search
    var projectCalendar = projectCalendars[0]


    events = projectCalendar.events()

    // This sorts all events so it may take a while
    events.sort(function (a,b){
        if (a.startDate() > b.startDate()) return -1;
        if (a.startDate() < b.startDate()) return 1;
        return 0
        });


    // Script Editor only outputs one value, so an array to show that start dates are in order
    var holderArray= []

    for (let i=0; i < events.length; i++){
        holderArray.push(events[i]);
        }

    // Most Recent event is now first as sort is decending

    events[0].startDate();
  

Calendar Update event property (create new event with new property)

Open in Editor: Jump to Index | Top


    // Unlike elements which can be added, properties cannot be changed, but new events must be created with new property and the previous event deleted.
    // is this correct? https://stackoverflow.com/questions/9454863/updating-javascript-object-property/48209957
    // This script creates an example event and then based on that event creates a new event with a new description property.

    // Add standard library for dialog boxes
    var app = Application.currentApplication();
    app.includeStandardAdditions = true;

    //Set Calendar to be the Application Calendar
    var Calendar = Application('Calendar');

    //Set name of Calendar you are using
    var calendarUsed = "Demo";

    //use Demo as the used Calendar by searching for it.
    var projectCalendars = Calendar.calendars.whose({name: calendarUsed});
    //Use the first result that matches name search
    var projectCalendar = projectCalendars[0];

    //You need the time now as an object
    var timeNow = new Date();

    //inAnHour as well
    var inAnHour = new Date();

    //Create Date object one hour ago for search criteria
    inAnHour.setHours(timeNow.getHours()+1);


    //Create new event with values from pervious event and end time of timeNow
    newEvent=Calendar.Event({summary: "Demo Event", startDate: timeNow, endDate: inAnHour});

    // Push the event to the calendar
    projectCalendar.events.push(newEvent);

    // Get ID of last created event to be used to delete the event without description
    var eventWithoutDescriptionId = projectCalendar.events.last.id()


    var descriptionText = "This event was created with a description";

    //Create new event with same valuses as it replaces and new descritption
    eventWithDescription=Calendar.Event({summary: "Demo Event" , startDate: timeNow, endDate: inAnHour, description: descriptionText})

    // push the event to the calendar
    projectCalendar.events.push(eventWithDescription)

    //Delete the event without description.
    try {
    Calendar.delete(projectCalendar.events.byId(eventWithoutDescriptionId))
    }
    catch(err){
        var errorMsg = app.displayDialog("Error", {
        buttons: ["Cancel", "Continue"],
        defaultButton: "Continue"
        })
    };
  

Finder Full path to this file

Open in Editor: Jump to Index | Top

  // Provids the full path to current files as a Path object use toString() if you want a string

    var app = Application.currentApplication();
    app.includeStandardAdditions = true;

    //
    thePath = app.pathTo(this);
  

Finder Item properties

Open in Editor: Jump to Index | Top


    // Looking at the properties of diskItems

    var Finder = Application("Finder");
    var SystemEvents = Application("System Events");

    var sourcePathStr = "~/Demo/sampleDir"
    var expandedSourcePathStr = $(sourcePathStr).stringByStandardizingPath.js
    //Result: "/Users/adkj/Demo/sampleDir"

    // function sourceFolder
    var sourceFolder = SystemEvents.aliases.byName(expandedSourcePathStr);
    //Result: Application("System Events").aliases.byName("/Users/adkj/Demo/sampleDir")

    //function container
    var container = sourceFolder.container();
    //Result: Application("System Events").folders.byName("Macintosh HD:Users:adkj:Demo")

    // String containerPath
    var containerPath = container.path();
    //Result: "Macintosh HD:Users:adkj:Demo"
    // Create an array of items functions to be processed
    var items = SystemEvents.aliases.byName(sourcePathStr).diskItems;
    items[1]()
    //Result: Path("/Users/adkj/Demo/sampleDir/samplefile.rtf")

    items[1].class()
    //Result: "file"

    items[1].name()
    //Result: "samplefile.rtf"

    items[0].path()
    //Result: "Macintosh HD:Users:adkj:Demo:sampleDir:.DS_Store";
  

Finder Moving and item properties

Open in Editor: Jump to Index | Top


    var app = Application.currentApplication();
    app.includeStandardAdditions = true;

    var Finder = Application("Finder");
    var SystemEvents = Application("System Events");

    // Ask a folder to process

    var sourcePathStr = "~/Demo/sampleDir"

    //Expands ~ to be full user path
    var expandedSourcePathStr = $(sourcePathStr).stringByStandardizingPath.js

    // Allows for running the script multiple times
    var duplicateAvoider = Date.now().toString()


    // function sourceFolder
    var sourceFolder = SystemEvents.aliases.byName(expandedSourcePathStr);
    //Result: Application("System Events").aliases.byName("/Users/adkj/Demo/sampleDir")

    // Create the destination folder

    //function container
    var container = sourceFolder.container();
    //Result: Application("System Events").folders.byName("Macintosh HD:Users:adkj:Demo")

    // String containerPath
    var containerPath = container.path();
    //Result: "Macintosh HD:Users:adkj:Demo"

    // .make is function/method from Standard Suite
    var destinationFolder = Finder.make(
        {
             new: "folder",
            at: containerPath,
            withProperties:
            {
                name: sourceFolder.name() + " - New"

            }
        }
    );

    // Create an array of items functions to be processed
    var items = SystemEvents.aliases.byName(sourcePathStr).diskItems;
    items[0]()
    //Result: Path("/Users/adkj/Demo/sampleDir/samplefile.rtf")

    items[0].class()
    //Result: "file"

    items[0].name()
    //Result: "samplefile.rtf"

    items[1].path()
    //Result: "Macintosh HD:Users:adkj:Demo:sampleDir:.DS_Store"


    //Finder.move("Macintosh HD:Users:adkj:Demo:sampleDir:samplefile.rtf", { to: "Macintosh HD:Users:adkj:Demo:sampleDir - New" });
  

Finder Open Window

Open in Editor: Jump to Index | Top


    // Script to Open a Finder Window with a folder and bring to the front
    // Requires ~/Demo

    var Finder = Application('Finder');

    var demoDir = "~/Demo"

    //Resolves the ~ to be the home directory path
    var fullDemoDir = $(demoDir).stringByStandardizingPath.js

    //Opens Finder window containing ~/Demo
    // Brings Path object into view
    Finder.reveal(Path(fullDemoDir));

    //Brings finder to front
    Finder.activate();
  

Finder make folder

Open in Editor: Jump to Index | Top

  // Make a new directory
    var app = Application.currentApplication();
    app.includeStandardAdditions = true;

    var Finder = Application("Finder");

    Finder.make(
        {
             new: "folder",
            //Requires password to create folder here
            at: "Macintosh HD:Users",
            withProperties:
            {
                name: "Made by JXA"

            }
        }
    );
  

Finder moving files

Open in Editor: Jump to Index | Top


    // Move files from one directory to another
    // based on https://stackoverflow.com/questions/31710494/moving-created-files-with-jxa
  
    'use strict';

    var app = Application.currentApplication()
    app.includeStandardAdditions = true

    var Finder = Application('Finder');

    // Create a Path object
    var sourceFile = Path("/User/adkj/Demo/sample.rtf");

    var destintationFile = "/Users/adkj/Demo2/sample" ;

    var destFolder=Path("/Users/adkj/Demo2");

    var strPathSource = $(sourceFile).toString();

    var strPathDest = $(destFolder).toString();

    Finder.move(strPathSource, { to:strPathDest, replacing: true});
  

Investigate Failed Calendar identifier

Open in Editor: Jump to Index | Top

  //.calendaridentifier()
    var calTaskBox = Application('Calendar').calendars[9]
    calTaskBox.calendarIdentifier();
  

JS Array Sort by Date

Open in Editor: Jump to Index | Top

  // Example of sorting by the Date Object

    array = [new Date(), new Date(100001), new Date(100100800000), new Date(1989, 9, 11, 8, 46, 00, 0)]

    var sortedArray = array.sort((a, b) => a.valueOf() - b.valueOf());
  

JS exploration

Open in Editor: Jump to Index | Top


    //array of object's enumerable string properties
    Object.keys(Application('Calendar').calendars[12].events)
    //Result : ["0", "1", "2", "3", "4", "5"]


    //Get name of calendar 12
    Application('Calendar').calendars[12].name()
    //Result: "Demo"

    //Summary is the name of the event
    Application('Calendar').calendars[12].events.summary()
    //Result: ["Demo Project 1 - makeing video", "Cheese Making - Researching soy cheddar", "Blog Apple launchd", "Blog research ", "Automating TimeMachine Backups", "Chess"];
  

JXA AppleScript in JXA

Open in Editor: Jump to Index | Top


    (() => {
        'use strict';

        // evalAS :: String -> IO String
        const evalAS = s => {
            const
                a = Application.currentApplication(),
                sa = (a.includeStandardAdditions = true, a);
            return sa.doShellScript(
                ['osascript -l AppleScript <<OSA_END 2>/dev/null']
                .concat([s])
                .concat('OSA_END')
                .join('\n')
            );
        };

        return evalAS('say "hello world"');

    })();
  

JXA Quit Application

Open in Editor: Jump to Index | Top

  // Quit an open Application

    var pages = Application('Pages');
    pages.quit();
  

Mission Control Manage Desktops and open apps

Open in Editor: Jump to Index | Top


    // I found this somewhere, reference it when found again

    Application("Mission Control").launch()

    var proc = Application("System Events").processes['Dock']
    var group = proc.groups[0].groups[0].groups[1]

    var bs = group.buttons.whose({ description: "add desktop"})
    Application("System Events").click(bs[0])

    delay(0.5)
    var li = group.lists[0]
    Application("System Events").click(li.buttons[li.buttons.length - 1])

    delay(0.5)
    Application("Calendar").activate();
    Application("Reminders").activate();
  

Music Toggle Play Pause

Open in Editor: Jump to Index | Top

  // Toggle between Playing and pausing current song

    Music = Application('Music');

    Music.playpause();
  

ObjC Read file contents

Open in Editor: Jump to Index | Top


    // Maybe from JXA cookbook

    (function () {
        'use strict';

        // GENERIC FUNCTIONS ------------------------------------------------------

        // doesFileExist :: String -> Bool
        function doesFileExist(strPath) {
            var error = $();
            return $.NSFileManager.defaultManager
                .attributesOfItemAtPathError($(strPath)
                    .stringByStandardizingPath, error), error.code === undefined;
        };

        // lines :: String -> [String]
        function lines(s) {
            return s.split(/[\r\n]/);
        };

        // readFile :: FilePath -> maybe String
        function readFile(strPath) {
            var error = $(),
                str = ObjC.unwrap(
                    $.NSString.stringWithContentsOfFileEncodingError($(strPath)
                        .stringByStandardizingPath, $.NSUTF8StringEncoding, error)
                ),
                blnValid = typeof error.code !== 'string';
            return {
                nothing: !blnValid,
                just: blnValid ? str : undefined,
                error: blnValid ? '' : error.code
            };
        };

        // show :: a -> String
        function show(x) {
            return JSON.stringify(x, null, 2);
        };

        // TEST -------------------------------------------------------------------
        var strPath = '~/DeskTop/random.txt';

        return doesFileExist(strPath) ? function () {
            var dctMaybe = readFile(strPath);
            return dctMaybe.nothing ? dctMaybe.error : show(lines(dctMaybe.just));
        }() : 'File not found:\n\t' + strPath;
    })();
  

ObjC Read folder files

Open in Editor: Jump to Index | Top


    // Uses Objective C to read file names in a given folder.
    // Copied from the JXA/Cookbook https://github.com/JXA-Cookbook/JXA-Cookbook

        // listDirectory :: FilePath -> [FilePath]
        function listDirectory(strPath) {
            fm = fm || $.NSFileManager.defaultManager;

            return ObjC.unwrap(
                    fm.contentsOfDirectoryAtPathError($(strPath)
                        .stringByExpandingTildeInPath, null))
                .map(ObjC.unwrap);
        }

        var fm = $.NSFileManager.defaultManager;

        listDirectory('~/Documents');
  

Reminders Create new List

Open in Editor: Jump to Index | Top

  // Create new Reminders List

    var Reminders = Application("Reminders");

    //Create new List object. Other properties are color, container, and emblem.
    var newReminderList = Reminders.List({name: "TEST"});

    Reminders.lists.push(newReminderList);
  

Reminders Explore List Properties

Open in Editor: Jump to Index | Top

  // Extracting Reminder list properties

    var Reminders = Application("Reminders");
  

Reminders Show reminder byId

Open in Editor: Jump to Index | Top


    var Reminders = Application("Reminders")

    // Open reminders on the screen to see selected reminder
    Reminders.activate()

    //Reminders.lists.byName('List 1').show()

    // You need to find a correct Id.
    Application("Reminders").reminders.byId("x-apple-reminder://D20AFA87-6606-48D9-A4D0-758B1A8F07DB").show();
  

Reminders create new Reminder

Open in Editor: Jump to Index | Top


    // Create new Reminder
    // from https://www.richardhyde.net/2019/04/16/New-Reminder-Using-JXA.html

    var reminders = Application("Reminders");
    var newReminder = reminders.Reminder({ name: "Title for reminder", body: "Notes for the reminder"});
    reminders.lists.byName("List Name").reminders.push(newReminder);
  

SA Error popup

Open in Editor: Jump to Index | Top


    // Include Apple UI library
    var app = Application.currentApplication()
    app.includeStandardAdditions = true

    var errorMsg = app.displayDialog("Error", {
    buttons: ["Cancel", "Continue"],
    // icon alternatives are stop, note, caution
    withIcon: "stop",
    defaultButton: "Continue"
    });
  

SA File exists

Open in Editor: Jump to Index | Top

  var app = Application.currentApplication()
    app.includeStandardAdditions = true

    var sourceFilePath = Path("/User/adkj/Demo/sample.rtf");
    var sourceFile = "/User/adkj/Demo/sample.rtf"



    app.exists(sourceFile)
    // Result: true;
  

SA Launch and Quit Application

Open in Editor: Jump to Index | Top

  var Reminders = Application('Reminders');

    Reminders.activate();

    delay(4)

    Reminders.quit();
  

SA Run shell command

Open in Editor: Jump to Index | Top

  var app = Application.currentApplication();
    app.includeStandardAdditions = true;

    // Starts screensaver
    app.doShellScript('/System/Library/CoreServices/ScreenSaverEngine.app/Contents/MacOS/ScreenSaverEngine -background &');
  

SA Spotlight deeplink

Open in Editor: Jump to Index | Top

  //Spotlight to use Deep link, in this case Red Hot Timer

    app = Application.currentApplication();
    app.includeStandardAdditions = true;

    app.openLocation("timer://30m");
  

SA UI to Choose from Listed array elements

Open in Editor: Jump to Index | Top


    // To use UI elements
    var app = Application.currentApplication()
    app.includeStandardAdditions = true

    // Array of things to choose from
    var choices = ["Red", "Orange", "Yellow", "Green", "Blue", "Indigo", "Violet"]
    var chooseItem = app.chooseFromList(choices, {
    defaultAnswer: "Red",
        withPrompt: "Choose a color"
    }
    )

    // Returns array of choices
    chooseItem

    //Stringify the choice
    choosenItem = chooseItem[0];
  

SA User information

Open in Editor: Jump to Index | Top

  // Get user information

    var SystemEvents = Application('System Events')


    SystemEvents.currentUser.homeDirectory()
    SystemEvents.currentUser();
  
  // Get user information

    var SystemEvents = Application('System Events')


    SystemEvents.currentUser.homeDirectory()
    SystemEvents.currentUser();
  

Other Resources

Jump to Top
  • JXA Cookbook on Github
  • JXA Release Notes
  • JXA tutorial from WWDC
  • JXA Resources
  • Apple Docs
  • AppleScript Language Guide
  • Hack Mag JXA intro
  • Mac Stories: Getting Started with JXA
  • Automating Chrome
  • Japanese JXA Examples