Installations
npm install webext-options-sync
Developer Guide
Typescript
Yes
Module System
ESM
Min. Node Version
>=18
Node Version
23.1.0
NPM Version
10.9.0
Score
72.1
Supply Chain
99.5
Quality
81.6
Maintenance
100
Vulnerability
100
License
Releases
Contributors
Unable to fetch Contributors
Languages
TypeScript (100%)
Developer
Download Statistics
Total Downloads
221,676
Last Day
24
Last Week
252
Last Month
2,796
Last Year
30,732
GitHub Statistics
154 Stars
198 Commits
12 Forks
4 Watching
1 Branches
11 Contributors
Bundle Size
18.37 kB
Minified
6.02 kB
Minified + Gzipped
Sponsor this package
Package Meta Information
Latest Version
4.3.0
Package Id
webext-options-sync@4.3.0
Unpacked Size
29.14 kB
Size
9.00 kB
File Count
7
NPM Version
10.9.0
Node Version
23.1.0
Publised On
17 Nov 2024
Total Downloads
Cumulative downloads
Total Downloads
221,676
Last day
-62.5%
24
Compared to previous day
Last week
-50.6%
252
Compared to previous week
Last month
-17.6%
2,796
Compared to previous month
Last year
-19.2%
30,732
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
webext-options-sync
Helps you manage and autosave your extension's options.
Main features:
- Define your default options
- Add autoload and autosave to your options
<form>
- Run migrations on update
- Import/export helpers
This also lets you very easily have separate options for each domain with the help of webext-options-sync-per-domain
.
Install
You can download the standalone bundle and include it in your manifest.json
.
Or use npm
:
1npm install webext-options-sync
1import OptionsSync from 'webext-options-sync';
The browser-extension-template repo includes a complete setup with ES Modules, based on the advanced usage below.
Usage
This module requires the storage
permission in manifest.json
:
1{ 2 "name": "My Cool Extension", 3 "permissions": [ 4 "storage" 5 ] 6}
Simple usage
You can set and get your options from any context (background, content script, etc):
1/* global OptionsSync */ 2const optionsStorage = new OptionsSync(); 3 4await optionsStorage.set({showStars: 10}); 5 6const options = await optionsStorage.getAll(); 7// {showStars: 10}
Note: OptionsSync
relies on chrome.storage.sync
, so its limitations apply, both the size limit and the type of data stored (which must be compatible with JSON).
Advanced usage
It's suggested to create an options-storage.js
file with your defaults and possible migrations, and import it where needed:
1/* global OptionsSync */
2window.optionsStorage = new OptionsSync({
3 defaults: {
4 colorString: 'green',
5 anyBooleans: true,
6 numbersAreFine: 9001
7 },
8
9 // List of functions that are called when the extension is updated
10 migrations: [
11 (savedOptions, currentDefaults) => {
12 // Perhaps it was renamed
13 if (savedOptions.colour) {
14 savedOptions.color = savedOptions.colour;
15 delete savedOptions.colour;
16 }
17 },
18
19 // Integrated utility that drops any properties that don't appear in the defaults
20 OptionsSync.migrations.removeUnused
21 ]
22});
Include this file as a background script: it's where the defaults
are set for the first time and where the migrations
are run. This example also includes it in the content script, if you need it there:
1{ 2 "background": { 3 "scripts": [ 4 "webext-options-sync.js", 5 "options-storage.js", 6 "background.js" 7 ] 8 }, 9 "content_scripts": [ 10 { 11 "matches": [ 12 "https://www.google.com/*", 13 ], 14 "js": [ 15 "webext-options-sync.js", 16 "options-storage.js", 17 "content.js" 18 ] 19 } 20 ] 21}
Then you can use it this way from the background
or content.js
:
1/* global optionsStorage */
2async function init () {
3 const {colorString} = await optionsStorage.getAll();
4 document.body.style.background = colorString;
5}
6
7init();
And also enable autosaving in your options page:
1<!-- Your options.html --> 2<form> 3 <label>Color: <input name="colorString"/></label><br> 4 <label>Show: <input type="checkbox" name="anyBooleans"/></label><br> 5 <label>Stars: <input name="numbersAreFine"/></label><br> 6</form> 7 8<script src="webext-options-sync.js"></script> 9<script src="options-storage.js"></script> 10<script src="options.js"></script>
1// Your options.js file
2/* global optionsStorage */
3
4optionsStorage.syncForm(document.querySelector('form'));
Form autosave and autoload
When using the syncForm
method, OptionsSync
will serialize the form using dom-form-serializer, which uses the name
attribute as key
for your options. Refer to its readme for more info on the structure of the data.
Any user changes to the form are automatically saved into chrome.storage.sync
after 300ms (debounced). It listens to input
events.
Input validation
If your form fields have any validation attributes they will not be saved until they become valid.
Since autosave and validation is silent, you should inform the user of invalid fields, possibly via CSS by using the :invalid
selector:
1/* Style the element */ 2input:invalid { 3 color: red; 4 border: 1px solid red; 5} 6 7/* Or display a custom error message */ 8input:invalid ~ .error-message { 9 display: block; 10}
API
const optionsStorage = new OptionsSync(setup?)
Returns an instance linked to the chosen storage. It will also run any migrations if it's called in the background.
setup
Type: object
Optional. It should follow this format:
1{ 2 defaults: { // recommended 3 color: 'blue' 4 }, 5 migrations: [ // optional 6 savedOptions => { 7 if(savedOptions.oldStuff) { 8 delete savedOptions.oldStuff 9 } 10 } 11 ], 12}
defaults
Type: object
A map of default options as strings or booleans. The keys will have to match the options form fields' name
attributes.
migrations
Type: array
A list of functions to run in the background
when the extension is updated. Example:
1{ 2 migrations: [ 3 (options, defaults) => { 4 // Change the `options` 5 if(options.oldStuff) { 6 delete options.oldStuff 7 } 8 9 // No return needed 10 }, 11 12 // Integrated utility that drops any properties that don't appear in the defaults 13 OptionsSync.migrations.removeUnused 14 ], 15}
[!NOTE] The
options
argument will always include thedefaults
as well as any options that were saved before the update.
storageName
Type: string
Default: 'options'
The key used to store data in chrome.storage.sync
logging
Type: boolean
Default: true
Whether info and warnings (on sync, updating form, etc.) should be logged to the console or not.
storageType
Type: 'local' | 'sync'
Default: sync
What storage area type to use (sync storage vs local storage). Sync storage is used by default.
Considerations for selecting which option to use:
- Sync is default as it's likely more convenient for users.
- Firefox requires
browser_specific_settings.gecko.id
for thesync
storage to work locally. - Sync storage is subject to much tighter quota limitations, and may cause privacy concerns if the data being stored is confidential.
optionsStorage.set(options)
This will merge the existing options with the object provided.
Note: Any values specified in default
are not saved into the storage, to save space, but they will still appear when using getAll
. You just have to make sure to always specify the same defaults
object in every context (this happens automatically in the Advanced usage above.)
options
Type: object
Default: {}
Example: {color: red}
A map of default options as strings, booleans, numbers and anything accepted by dom-form-serializer’s deserialize
function.
optionsStorage.setAll(options)
This will override all the options stored with your options
.
optionsStorage.getAll()
This returns a Promise that will resolve with all the options.
optionsStorage.onChanged(callback, signal?)
Listens to changes in the storage and calls the callback when the options are changed. The callback is called with the new and old options.
callback
Type: (newOptions: object, oldOptions: object) => void
signal
Type: AbortSignal
If provided, the callback will be removed when the signal is aborted.
optionsStorage.syncForm(form)
Any defaults or saved options will be loaded into the <form>
and any change will automatically be saved via chrome.storage.sync
. It also looks for any buttons with js-import
or js-export
classes that when clicked will allow the user to export and import the options to a JSON file.
options-sync:save-success
: Fired on the edited field when the form is saved.options-sync:save-error
: Fired on the edited field when the form is not saved due to an error. The error is passed as thedetail
property.
Saving can fail when the storage quota is exceeded for example. You should handle this case and display a message to the user.
form
Type: HTMLFormElement
, string
It's the <form>
that needs to be synchronized or a CSS selector (one element). The form fields' name
attributes will have to match the option names.
optionsStorage.stopSyncForm()
Removes any listeners added by syncForm
.
optionsStorage.exportToFile()
Opens the browser’s "save file" dialog to export options to a JSON file. If your form has a .js-export
element, this listener will be attached automatically.
optionsStorage.importFromFile()
Opens the browser’s file picker to import options from a previously-saved JSON file. If your form has a .js-import
element, this listener will be attached automatically.
Related
- webext-options-sync-per-domain - Wrapper for
webext-options-sync
to have different options for each domain your extension supports. - webext-storage-cache - Map-like promised cache storage with expiration.
- webext-dynamic-content-scripts - Automatically registers your content_scripts on domains added via permission.request.
- Awesome-WebExtensions - A curated list of awesome resources for WebExtensions development.
- More…
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
0 existing vulnerabilities detected
Reason
license file detected
Details
- Info: project has a license file: license:0
- Info: FSF or OSI recognized license: MIT License: license:0
Reason
6 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 6
Reason
dependency not pinned by hash detected -- score normalized to 1
Details
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/fregante/webext-options-sync/ci.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/fregante/webext-options-sync/ci.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/fregante/webext-options-sync/ci.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/fregante/webext-options-sync/ci.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:42: update your workflow using https://app.stepsecurity.io/secureworkflow/fregante/webext-options-sync/ci.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/fregante/webext-options-sync/ci.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/esm-lint.yml:91: update your workflow using https://app.stepsecurity.io/secureworkflow/fregante/webext-options-sync/esm-lint.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/esm-lint.yml:92: update your workflow using https://app.stepsecurity.io/secureworkflow/fregante/webext-options-sync/esm-lint.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/esm-lint.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/fregante/webext-options-sync/esm-lint.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/esm-lint.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/fregante/webext-options-sync/esm-lint.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/esm-lint.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/fregante/webext-options-sync/esm-lint.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/esm-lint.yml:39: update your workflow using https://app.stepsecurity.io/secureworkflow/fregante/webext-options-sync/esm-lint.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/esm-lint.yml:48: update your workflow using https://app.stepsecurity.io/secureworkflow/fregante/webext-options-sync/esm-lint.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/esm-lint.yml:60: update your workflow using https://app.stepsecurity.io/secureworkflow/fregante/webext-options-sync/esm-lint.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/esm-lint.yml:69: update your workflow using https://app.stepsecurity.io/secureworkflow/fregante/webext-options-sync/esm-lint.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/esm-lint.yml:78: update your workflow using https://app.stepsecurity.io/secureworkflow/fregante/webext-options-sync/esm-lint.yml/main?enable=pin
- Warn: npmCommand not pinned by hash: .github/workflows/ci.yml:48
- Warn: npmCommand not pinned by hash: .github/workflows/ci.yml:22
- Warn: npmCommand not pinned by hash: .github/workflows/ci.yml:34
- Warn: npmCommand not pinned by hash: .github/workflows/esm-lint.yml:41
- Warn: npmCommand not pinned by hash: .github/workflows/esm-lint.yml:50
- Warn: npmCommand not pinned by hash: .github/workflows/esm-lint.yml:62
- Warn: npmCommand not pinned by hash: .github/workflows/esm-lint.yml:73
- Warn: npmCommand not pinned by hash: .github/workflows/esm-lint.yml:81
- Warn: npmCommand not pinned by hash: .github/workflows/esm-lint.yml:97
- Warn: npmCommand not pinned by hash: .github/workflows/esm-lint.yml:23
- Info: 0 out of 16 GitHub-owned GitHubAction dependencies pinned
- Info: 3 out of 13 npmCommand dependencies pinned
Reason
Found 2/30 approved changesets -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
- Warn: no topLevel permission defined: .github/workflows/ci.yml:1
- Warn: no topLevel permission defined: .github/workflows/esm-lint.yml:1
- Info: no jobLevel write permissions found
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'main'
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 13 are checked with a SAST tool
Score
4.1
/10
Last Scanned on 2025-01-06
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn MoreOther packages similar to webext-options-sync
webext-options-sync-per-domain
Helps you manage and autosave your extension's options, separately for each additional permission.
webext-sync
Sync data between a web extension's background, popup, options and content scripts. Works cross-browser, with MV3 and MV2.
webext-options
webext-options-sync will soon be renamed to webext-options, but this package is currently empty