An open-source userscript editor for Safari.
- Installation
- Getting Help
- UI Overview
- Metadata
- Save Location
- FAQs
- Contributing
- Support
- Privacy Policy
- License
Userscripts is available for iOS (+ipadOS) and macOS. For all versions, installation is done through Apple's App Store. On macOS, versions prior to 4.x were made available to download and install directly from the repository, but due to changes in the way Apple allows developers to distribute apps built with the WebExtension API, that is no longer an option.
If you encounter a problem while using this app/extension or are in need of some assistance, please open an issue here in the repository. When doing so, please provide as much detail as possible. This includes listing you system specs and what website and script you are trying to execute. Please follow the issue template!
- Extension button - click this button to open the extension interface
- Filter bar - use this input to filter items in the sidebar, by name
- Sort button - changes the order of the items in the sidebar by name or modified time
- Sidebar buttons - described left to right
- The
settingsbutton (represented by a cog) displays the settings modal (discussed below) - The
plusbutton allows users to add new itemsNew CSSis a "userscript" that expects CSS codeNew Javascriptis a prototypical userscript that expects Javascript codeNew Remoteallows the user to add a remote hosted userscript (or style) by inputting the web address (ex:https://www.k21p.com/example.user.js)
- The
- Item toggle - this toggle enables or disables an item
- Item - this is the userscript (or style), clicking on it will load it's contents into the editor - you can hide descriptions in the settings area!
- Editor buttons (top) - described left to right
- Update button - this button allows you to update userscripts that meet the following conditions
- metadata contains
@versiontag - metadata contains
@updateURLtag
- metadata contains
- Download button - click this button to download a copy of your userscript
- Note: every userscript that is displayed in the interface is already present on your local machine, at your save location - the download button offers a quick way to retrieve a copy of that file, without needing to click the settings button, and then the save location link within the settings modal
- Trash button - moves the currently loaded userscript to the trash bin - it will subsequently be removed from the interface and save location
- Update button - this button allows you to update userscripts that meet the following conditions
- Editor buttons (bottom)
Discard- while editing, reverts any unsaved changes you've made to a userscriptSave- while editing, saves all changes you've made to a userscriptCommand + Sis the keyboard shortcut for the action
- Auto Close Brackets - toggles on/off auto closing of brackets in the editor
- this affects the following characters:
() [] {} "" ''
- this affects the following characters:
- Auto Hint - automatically shows completion hints while editing
- Hide Descriptions - hides the item descriptions in the sidebar
- Show Invisibles - toggles the display of invisible characters in the editor
- Javascript Linter - toggles basic Javascript linting within the editor
- Tab Size - the number of spaces a tab is equal to while editing, obviously defaults to
4because using2spaces is absolute insanity - Enable Injection - toggle on/off script injection for the pages you visit (this is the on/off switch)
- Show Toolbar Count - displays a badge on the toolbar icon with a number that represents how many enabled scripts match the url for the page you are on
- Save Location - where your file are currently located and being saved to (click the blue text to open location)
- Change Save Location (cogs icon) - this button, located directly to the right of the save location, is a shortcut for opening the host app, which will allow you to change the save location
- Global Blacklist - all domain patterns listed here will be globally ignored for script injection
- Open button - opens the extension browser page
- Enable Injection toggle - turns on/off page script inject (on/off switch)
Userscripts Safari currently supports the following userscript metadata:
@name- This will be the name that displays in the sidebar and be used as the filename - you can not use the same name for multiple files of the same type@description- Use this to describe what your userscript does - this will be displayed in the sidebar - there is a setting to hide descriptions@match- Domain match patterns - you can use several instances of this field if you'd like multiple domain matches - view this article for more information on constructing patterns- Note: this extension only supports
http/s
- Note: this extension only supports
@exclude-match- Domain patterns where you do not want the script to run@include- Used to match against urls for injection, globs and regular expressions are allowed, read more here@exclude- Functions in a similar way as@includebut rather than injecting, a match against this key's value will prevent injection@inject-into- allows the user to choose which context to inject the script into- allows the user to choose which context to inject the script into
- values: auto (default), content, page
- works like violentmonkey
@run-at- allows the user to choose the injection timing
- document-start, document-end (default), document-idle
- works like violentmonkey
- JS Only
@weight- allows the user to further adjust script injection timing
- can be used to ensure one script injects before another
- ONLY accepts integers (floats, strings and everything else will be ignored)
- min value = 1, max value = 999, higher numbers (“heavier”) execute earlier
@require- allows users to include remote resources in their scripts
- the value must be a valid url, currently no local file support
- must require a resource of the same file type (JS for JS, CSS for CSS)
- when a resource is required, it is downloaded and saved locally
- the resources is downloaded once at save and never checked for updates or parsed in anyway
- if you want to update the require resources, and the url does not change, you must remove the resources, save, then re-input it
- require remote resources at your own risk, the extension never validates remote resource code in any way and be aware that using remote resources from untrusted sources can jeopardize your personal security
@version- used to determine the current version of a userscript
- when paired with
@updateURL, this will allow the user to update a userscript from a remote source, if the version on their machine is<version at the update URL @versiondoes nothing by itself, it needs to be paired with@updateURLfor remote updating to function properly
@updateURL- the remote url to check version against
- if the version of the file located at the update URL is
>the version on the local machine, the file will be updated @updateURLdoes nothing by itself, it needs to be paired with@versionfor remote updating to function properly
@downloadURL- optional download location for a remotely updateable file (*i.e. a file that has both
@versionand@updateURL) - when paired with
@versionand@updateURL, if the local version is<the version of the file that@updateURLpoints to, the extension will attempt to update the file's code with the contents of the file located at the@downloadURL @downloadURLdoes nothing by itself, it needs@versionand@updateURLto present in order to function properly
- optional download location for a remotely updateable file (*i.e. a file that has both
@noframes- this key takes no value
- prevents code from being injected into nested frames
All userscripts need at least 1 @match or @include to run!
On macOS this is the directory where the app/extension will read from and write to (if working with the included code editor). For both iOS and macOS this directory is changed by opening the containing app and clicking the respective "change location" button (verbiage may vary).
Script Directory Notes
- Close all instances of the extension UI (browser app and/or popup) before changing the scripts directory
- On macOS, after a directory outside of the default is selected, if you rename or move that selected directory, the extension will continue to read/write to that directory - the only way to remove the “link” is by trashing the folder or selecting a new save location
"Refused to execute a script" error(s), what should I do!?
You are seeing this error because of the website's Content Security Policy. Currently there is no way to allow extension content scripts to bypass CSPs in Safari.
Automatically, the extension will attempt to circumvent strict CSPs, but if you are still experiencing issues, trying setting the userscript metadata key/val
// @inject-into autoor// @inject-into content.You can read more about this in this issue.
Do I need to use the extension's editor to create new userscripts or to edit existing?
You can use your own editor to update and manage your files. As long as you are saving the files to the save location, and they are properly formatted, they should be injected. However, you must open the extension page beforehand. That means, if you create a new userscript and save it to the save location, before injection will occur properly, the extension page must be open by clicking the extension button in Safari.
What are the keyboard shortcuts?
While editing a file, clicking
Command + Swill save the file. While working the editor, clickingCommand + Fwill bring up the search bar.
When I use @require, where are the required files stored?
All required files are saved as Javascript files in the extension container folder in macOS 11.x. That folder is located in the default save location, at:
~/Library/Containers/Userscripts/Data/Documents/require/.If you move files from the require folder or manually edit the
manifest.jsonfile, you will likely break app/extension functionality.
Code level contributions are welcome. I prefer to collaborate directly with contributors rather than receiving spontaneous pull requests. If you feel you can improve the project in some way, please reach out to me by email or by opening an issue with your improvement/feature request.
Further, any issue marked "help wanted" is actively seeking assistance. Please respond to those issues with feedback, guidance or offers of coding assistance.
Please ensure your contributions align with the project's license before committing anything.
The quickest and easiest way to support the project is by leaving a positive review on the App Store if you enjoy the extension and want to see it improve in the future. Seeing these reviews let me know I am doing something right, or wrong, and motivates me to continue working on the project.
The second best way to help out is to sign up to beta test new versions of the app. Since this extension values your privacy, and does not collect any data from users, it is difficult to gauge how the extension is being used. By signing up to be a beta tester it not only allows you to test upcoming features, but also gives me the opportunity to elicit direct feedback from real users.
Userscripts does not collect any data from its users nor monitor activities or actions you perform within the application and extension. This means everything that you do with the application and extension is private to you and is never shared with the developers or third parties. Since there is no data collection, there is no data retention of any kind.
Copyright (c) 2021 Justin Wasack
Licensed under the GNU General Public License v3.0 license for all open source applications. A commercial license is required for all other applications.



