Blog

Release v4.5.0

Announcing nut.js v4.5.0: Unicode Support, Input Monitoring, and More!

We are thrilled to announce the release of nut.js v4.5.0! This update brings a host of new features and improvements that make automation scripting with nut.js more powerful and flexible than ever before. From enhanced Unicode support to a revamped low-level codebase, innovative input monitoring capabilities, and updates to our macOS screen capture functionality, there's a lot to unpack. Let's dive in!

Unicode Support Now in Core

One of the most significant enhancements in this release is the integration of general Unicode support directly into the nut.js core. Previously, handling Unicode characters was exclusive to the @nut-tree/bolt plugin. With this update, you can seamlessly work with Unicode characters without relying on external plugins.

What Does This Mean for You?

  • Simplified Workflow: No need to install additional plugins for Unicode support.
  • Broader Language Support: Easily automate tasks involving non-ASCII characters.
  • Improved Compatibility: Enhanced support for internationalization and localization efforts.

Refactored Low-Level Code: A Step Towards Cross-Language Compatibility

We've undertaken a comprehensive refactoring of the low-level code, separating it from the Node.js bindings and encapsulating it into a dedicated CMake library. This architectural overhaul has several exciting implications:

Benefits of the Refactoring

  • Easier Development: A cleaner codebase simplifies maintenance and feature addition.
  • Cross-Language Potential: Opens up possibilities to create bindings for other programming languages.
  • Performance Improvements: Optimized code leads to faster execution times.

Updated macOS Screen Capture Functionality

In response to deprecations in macOS APIs, we've rewritten the screen capture code for macOS. Some of the previously used APIs have been deprecated, and the new API we've adopted is only available starting from * macOS 14*. To ensure compatibility across different macOS versions, we've introduced separate packages:

  • For macOS versions earlier than 14: We maintain a package that uses the older APIs, ensuring continued support for users on earlier macOS versions.
  • For macOS 14 and later: A new package leverages the latest APIs, providing improved performance and stability.

What This Means for You

  • Automatic Compatibility: The appropriate screencapture package is automatically selected based on your macOS version during installation.
  • Seamless Transition: Users on older macOS versions can continue using nut.js without any disruption.
  • Enhanced Performance: Users on macOS 14 and later benefit from the improvements of the new APIs.

How to Get the Update

Simply update nut.js to the latest version, and the correct screen capture package will be handled for you. No additional steps are required on your part.

Introducing Input Monitoring with @nut-tree/bolt

The @nut-tree/bolt plugin has been supercharged with a new * *InputMonitor interface **, allowing you to monitor mouse and keyboard input events like never before.

EventEmitter Integration

Both the mouse and keyboard instances in nut.js are now EventEmitters. This means you can:

  • Register Callbacks: Attach functions to respond to specific keyboard commands or mouse positions.
  • Reactive Programming: Build scripts that react in real-time to user inputs.

Input Monitoring vs. Global Hotkeys

It's important to distinguish Input Monitoring from Global Hotkeys:

  • Non-Intrusive: Input Monitoring observes events without overriding existing functionalities.
  • Flexible Control: Unlike global hotkeys, which can interfere with system shortcuts, Input Monitoring allows for passive observation and reaction.

Use Case: Implementing a "Kill Switch"

One practical application of this feature is setting up a keyboard shortcut as a "kill switch" to abort an automation script. This is incredibly handy for both development and production environments where you might need to halt a script immediately.

How to Set Up a Kill Switch

import {keyboard, Key, mouse} from '@nut-tree/nut-js';

keyboard.on('keyDown', async (evt) => {
    if (isKeyEvent(evt, Key.Escape) && withModifiers(evt, [Key.LeftControl])) {
        // User pressed Ctrl + Esc, exit the script immediately
        process.exit(-1);
    }
});

mouse.on('mouseMove', async (evt) => {
    // Track mouse movements here
    console.log(`You're at position ${evt.targetPoint.x}, ${evt.targetPoint.y}`);

    if (isAtPosition(evt, new Point(100, 100))) {
        await mouse.click(Button.LEFT);
    }
});

system.startMonitoringInputEvents();

Additional Example: One-Time Event Listener with once

Another benefit of using EventEmitter is the ability to set up one-time event listeners using the once method. This allows you to execute a callback function only the first time an event occurs.

Use Case: Performing an Action on First Mouse Click

Suppose you want to perform a specific action the first time the user clicks the mouse. You can achieve this easily with once:

const {mouse} = require('@nut-tree/nut-js');

mouse.once('mouseDown', async (evt) => {
    console.log(`Mouse button ${evt.button} clicked for the first time.`);
    // Perform your one-time action here
});

This approach is especially useful when you need to initialize something or trigger an event only once, without manually removing the event listener afterward.

Tutorial: Reacting on User Input

Check out our tutorial on nut.js Input Monitoring to learn how to build dynamic applications.

Acknowledgment

This feature was developed in collaboration with GAL Digital GmbH. We thank their team for the excellent QA support and partnership.

Committing to Open Source Sustainability

We believe in giving back to the community that supports us. To date, we have donated $1,766.18 in open source sponsorships to projects and maintainers that our work relies on.

nut.js Open Source Sponsorships

Why This Matters

  • Community Growth: Supporting open source projects fosters innovation and collaboration.
  • Sustainability: Financial contributions help maintainers continue their important work.
  • Shared Success: Our project thrives because of the open source ecosystem, and we aim to keep it thriving.

What's Next?

One big feature done, many more to come! There's already something big on the horizon, so stay tuned for the next release.

Join the Conversation

Stay updated with the latest news and updates on the nut.js Discord server.

Thank you for your continued support!

Happy automating!

Simon