CLI for making browser web queries from a shell.
Install the package globally:
npm i -g @lexjs/web-cli
After installing, the web
command is ready to use without any initial setup.
web hello world
> https://google.com/search?q=hello%20world
To check the installed version, use the --version
option:
web --version
To get help with command options, use the --help
option:
web --help
To perform basic web queries from the terminal, provide space-separated values to the web
command:
web <values>
The app will then construct 1 or more queries based on the type of values and open them in the new browser tab(s).
There are 2 types of values:
- Keywords
- URLs
When providing keywords to the command, only 1 web query is created using the values as a search term:
web hello world
> https://google.com/search?q=hello%20world
In the absence of query options, the app uses the default search engine to construct the query and the default browser to open it in:
- After installation, you get a set of initial search engines that you can use, with Google being the default.
- The operating system's default browser is used unless the browsers configuration is set up.
You can change these defaults, as well as add new browsers and engines in the app's configuration.
Search Engine | CLI Value |
---|---|
google |
|
DuckDuckGo |
duckduckgo duck
|
MDN | mdn |
YouTube | youtube |
NPM | npm |
The CLI value can be either supplied to the engine
option or used as a custom flag.
When providing a URL as a value, the default behavior is to access that URL directly:
web github.com
> https://github.com
If multiple URLs are supplied, each URL is accessed via a separate web query:
web github.com npmjs.com developer.mozilla.org
> https://github.com
> https://npmjs.com
> https://developer.mozilla.org
If both keywords and URLs are provided, then all values are treated as search term keywords:
web most starred repos on github.com
> https://google.com/search?q=most%20starred%20repos%20on%20github.com
Query options give you control over the web queries by overriding app defaults.
To use an option in the command, prefix it with a double dash --
web --option
An option's short (1-letter) alias is prefixed by a single dash -
web -x
If an option requires a value (value options), provide it in one of the following ways (short aliases can also be used)
web --option=value
web --option value
The assignment syntax (
--option=value
) is preferred, especially when building larger web queries with many search term keywords. This helps avoid any confusion between what is an option's value and what is an actual keyword.
Short aliases can be combined together with a single dash -
as long as their combination is valid:
web -xyz
Which is effectively this:
web -x -y -z
Use Caution!
Combining short aliases of multiple value options will result in invalid queries when such combinations are followed by a value. It is recommended to combine only the flag options with no more than 1 value option placed at the very end of the combination (if the value option is placed in the middle, it will not get assigned the value).
The following are built-in options that require a value:
Option | Alias | Description | Config Type |
---|---|---|---|
browser |
b |
A browser app to open | browsers |
profile |
p |
A browser profile to use | browsers ⚙️ |
engine |
e |
A search engine (or website) to query | engines |
route |
r |
An engine's route to access | engines |
port |
: |
The port number to add to the URL | ❌ |
⚙️ indicates that configuration is required.
All value options, except profile
, work without any initial configuration but the options' usage becomes more enhanced when such config is set up. Refer to each option as well as browsers configuration and engines configuration for more details.
Options that do not require a value are called flags. The following are built-in flag options:
Option | Alias | Description |
---|---|---|
incognito |
i |
Open in incognito / private mode |
split |
❌ | Split values into separate web queries |
http |
❌ | Use the HTTP (non-secure) protocol |
peek |
❌ | Display the output without opening browser tabs |
Caveat!
Flag options can be assigned valuestrue
andfalse
. This is because, internally, flags areboolean
s. Using a flag option in the command automatically sets its value to "true" but the option will still accept a boolean value that's placed after it (even without the explicit=
sign). Therefore, make sure to not accidentally assign "true" or "false" to a flag if you do not intend it. Doing so will result in your web query missing the keyword "true" or "false" from the search term.
With browsers and engines configuration set up, you can also use custom flags which are created from the keys and aliases of browsers, browser profiles, and engines from the config files. Custom flags simplify your web queries by being a convenient substitute for value options.
Options can be placed anywhere in the command
web --browser=firefox this is --incognito an example --engine=duckduckgo search query
web -b=firefox this is -i an example -e=duckduckgo search query
Normally, you would place the options where they make sense visually (such as the beginning or the end of the command) or as you need them when you construct a query.
The above command will do the following:
- construct a web query using
- the keywords "this is an example search query"
- the DuckDuckGo search engine (
--engine=duckduckgo
)
- open the constructed query in a new Firefox tab (
--browser=firefox
) - in incognito / private mode (
--incognito
)
Specifies the browser app in which to open the new tab.
✅ Requires a value.
⭕ Configuration is optional.
web --browser=value
value
refers to the browser app name, or the browser's key or alias in the browsers config.
Note!
The command will not prevent you from specifying a value that refers to an invalid browser or to another non-browser application on your machine. As far as the program is concerned - any value provided to thebrowser
option is a possible browser app, so it will attempt to open it.
You can specify multiple browsers to open:
web --browser=value --browser=value ...
- The requested browser must be installed on the machine.
To use browser aliases as the option's value, set up browsers configuration.
Specifies what browser profile to use when opening a new tab.
✅ Requires a value.
✅ Requires browsers configuration.
web --profile=value
value
refers to the profile's key or alias in the browsers config.
The option should be used together with the
browser
option. However, if the browser option is NOT supplied, the program will use the config's default browser to find the provided profile value (see how default browser is determined in browsers configuration).
Important!
If the profile value is not found in the provided (or default) browser's config, the program will not open the query.
You can specify multiple profiles:
web --profile=value --profile=value ...
If multiple browser options are supplied, the program will attach each profile to one or more browsers that include that profile in their configs. So it is safe to supply multiple browsers and multiple profiles even if all profiles do not belong to each browser but as long as each profile can be matched with one or more browsers.
For example:
web --browser=b1 --browser=b2 --profile=p1 --profile=p2
Profile p1
might belong to browser b1
but not to browser b2
as long as the second profile p2
belongs to either b1
or b2
or both. This is just 1 example - there could be many different scenarios like this.
Remember, if no browser option is supplied, all profile values must belong to the default config browser (not to the operating system's default browser).
Different browsers can have the same profile keys and aliases in their configs.
- The browser app must support profiles.
- The profile must be set up in the config file.
To use the option, set up profiles in browsers configuration.
Specifies what search engine or website to query.
✅ Requires a value.
⭕ No initial configuration is required.
web --engine=value
value
refers to the engine's key or alias in the engines config or a URL.
For example:
web @lexjs/web-cli --engine=npm
> https://npmjs.com/search?q=@lexjs/web-cli
When supplying URL values to the command, this option overrides the default behavior of accessing the URLs directly. Instead, they are treated as search term keywords for the provided engine. For example:
web github.com --engine=google
> https://google.com/search?q=github.com
The option also accepts an arbitrary URL value:
web @lexjs/web-cli --engine=npmjs.com/search?q=
> https://npmjs.com/search?q=@lexjs/web-cli
Note!
Non-URL values are not allowed.
When using the option with an arbitrary URL, it behaves in the same way as any other engine from the config, meaning that you can use other options with it, such as --route
, --split
, or --http
.
Also note that since a URL value is a simple string and not an object that could better define an engine (for example, by having a query
property), the program will simply append it with whatever command values are supplied. If the URL has no query string that ends with an equals sign (=
), the values will be added after a forward-slash (/
):
web hello world --engine=example.com
> https://example.com/hello%20world
To define more engines and websites than the app defaults, add them to engines configuration.
Overrides the default behavior of querying a search engine by specifying the engine's route to access directly.
✅ Requires a value.
⭕ Configuration is optional.
The option must be used together with the engine
option. If the engine is NOT supplied, the validation will fail and the web query will not be performed.
web --route=value
value
refers to the engine's route to access.
For example, the following command adds "teapot" to the engine's URL to access the route directly instead of searching it as a keyword.
web --engine=google --route=teapot
> https://google.com/teapot
When supplying values to the command, each value is used in a separate web query as a URL path segment after the provided route.
For example, the following creates 3 distinct web queries:
web --engine=npm --route=package lodash axios express
> https://npmjs.com/package/lodash
> https://npmjs.com/package/axios
> https://npmjs.com/package/express
The option's value can be a key from an engine's routes
property in engines configuration. When this config property is set up, the program will search it first to find the provided value among the property's keys. If it is not there, then the supplied value itself is used to build the web query.
Setting up the routes
property can be useful when frequently accessing an engine's route that can be long to type or hard to remember the full path of.
For example, with the following GitHub engine config
"github": {
"name": "GitHub",
"url": "github.com",
"query": "search?q=",
"routes": {
"repos": "username?tab=repositories",
"stars": "username?tab=stars"
}
}
we can use repos
and stars
as a value of the route
option:
web --engine=github --route=repos
> https://github.com/username?tab=repositories
Adds the provided port number to the URL.
✅ Requires a number value.
❌ No configuration.
web example.com --port=3000
> https://example.com:3000/
If multiple ports are supplied, each one will create a separate query:
web example.com -: 3000 -: 5000
> https://example.com:3000/
> https://example.com:5000/
The program recognizes if an engine or a URL already includes a port and checks if it matches the option's value when building the final list of URLs:
web example.com:3000/api/users -: 3000 -: 5000
> https://example.com:3000/api/users
> https://example.com:5000/api/users
Opens web queries in a private / incognito mode.
🚩 Flag option - no value is required.
❌ No configuration.
web --incognito
Splits provided values into separate web queries.
🚩 Flag option - no value is required.
❌ No configuration.
web --engine=mdn Object Symbol class --split
> https://developer.mozilla.org/search?q=Object
> https://developer.mozilla.org/search?q=Symbol
> https://developer.mozilla.org/search?q=class
Uses the HTTP (non-secure) protocol when constructing the web queries.
🚩 Flag option - no value is required.
❌ No configuration.
Prevents opening browser tabs and only displays the output.
🚩 Flag option - no value is required.
❌ No configuration.
web [values] [options] --peek
To see where the config files are stored on your machine, use the config
option without a value.
web --config
> path/to/config/files
To open a desired config file, use the config
option with the browsers
or engines
value:
web --config=browsers
web --config=engines
Both browsers and engines configurations are in the JSON format, so the files will open in the OS default application for editing JSON.
Note!
When using this option with a value AND the corresponding config file does not exist, the program will create it. In the case of engines config, the newly created file will be populated with initial search engines. You have the option to change these initial engines (e.g. adding aliases or deleting an engine entirely from the config file).
The option can be used more than once (to open both files at the same time, for example):
web --config=browsers --config=engines
Optionally, you can supply 1 or more space-separated apps that should open the config files:
web --config=browsers code
web --config=engines notepad++
The apps should be installed on your machine.
Modifying each config requires you to follow their accepted data structures explained below.
Browsers configuration is a JSON file containing an object with browsers data. The following describes a browser object inside the JSON config file.
{
"<browser_key>": {
"isDefault": "boolean",
"alias": "string_or_array_of_strings",
"profiles": {
"<profile_key>": {
"directory": "string",
"isDefault": "boolean",
"alias": "string_or_array_of_strings"
}
}
}
}
You can add as many browser objects to the config file as you have browsers on your machine. Each browser object is separated by a comma, and trailing commas are not allowed in a JSON file.
Note!
Setting up browsers configuration does not limit you to using only the browsers in the config. You can still supply other browser values to thebrowser
option, but using custom flags is only available after setting up the config.
-
<browser_key>
: a string representing the browser app that is supplied to thebrowser
option. -
isDefault
: optional - accepts a boolean value indicating if the browser should be used as default. If not present, then the first browser object in the config file is used as default. If multiple browser objects have this property (which should be avoided), then the first one with it will be used as default. -
alias
: optional - accepts a string or array of strings that can be used instead of<browser_key>
. -
profiles
: optional - accepts an object that represents browser profiles:-
<profile_key>
: a string representing the browser profile that is supplied to theprofile
option. -
directory
: required - accepts a string representing the profile's exact directory name (NOT the full path, just the folder name). Different operating systems have different ways of storing user's browser profile data - please search how to find such folder on your OS, if you are not sure. -
isDefault
: optional - accepts a boolean value indicating if the browser's profile should be used as default. If not present, then the first profile object within the browser is used as default. If multiple profile objects inside the browser have this property (which should be avoided), then the first one with it will be used as default. -
alias
: optional - accepts a string or array of strings that can be used instead of<profile_key>
.
-
interface Browsers {
[browserKey: string]: {
isDefault?: boolean;
alias?: string | string[];
profiles?: Profiles;
};
}
interface Profiles {
[profileKey: string]: {
directory: string;
isDefault?: boolean;
alias?: string | string[];
};
}
{
"chrome": {
"alias": "c",
"profiles": {
"dev": {
"directory": "Profile 1",
"alias": "d"
},
"personal": {
"directory": "Profile 2",
"alias": "p"
}
}
},
"edge": {
"alias": "e",
"profiles": {
"dev": {
"directory": "Profile 1",
"alias": "d"
},
"school": {
"directory": "Profile 2",
"alias": ["s", "study"]
}
}
},
"firefox": {
"alias": ["f", "ff", "fox"]
}
}
Engines configuration is a JSON file containing an object with engines data. The following describes an engine object inside the JSON config file.
{
"<engine_key>": {
"name": "string",
"url": "string",
"query": "string",
"delimiter": "string",
"isDefault": "boolean",
"alias": "string_or_array_of_strings",
"routes": {
"<route_key>": "string"
}
}
}
You can add as many engine objects to the config file as you'd like to use. Each engine object is separated by a comma, and trailing commas are not allowed in a JSON file.
-
<engine_key>
: a string representing the search engine or website that is supplied to theengine
option. -
name
: required - accepts a string representing the name of the search engine / website. -
url
: required - accepts a string of the engine's base URL without the protocol and without the query string. For example, in a URL like this:https://google.com/search?q=whatever
- supply onlygoogle.com
. -
query
: optional - accepts a string representing the search engine's query string. Following the example above:https://google.com/search?q=whatever
- the query string issearch?q=
which sits between the engine's base url and the search keywords. To find an engine's query string, go to its URL then type anything in its search box and hit enter. You will find that most websites and search engines have their own query string that you can grab. If not, then that engine cannot be used for searching with the query string. -
delimiter
: optional - accepts a string (normally a single character) representing the delimiter between search term keywords. Sometimes you will find that search engines modify the search query URL by replacing the space with another character, such as a+
sign. If you find that the engine has a different delimiter, then provide it here. The default delimiter is the space character. -
isDefault
: optional - accepts a boolean value indicating if the engine should be used as default. If not present, then the first engine object in the config file is used as default. If multiple engine objects have this property (which should be avoided), then the first one with it will be used as default. -
alias
: optional - accepts a string or array of strings that can be used instead of<engine_key>
. -
routes
: optional - accepts an object that represents engine routes:-
<route_key>
: a string representing the route that is supplied to theroute
option. It accepts a string value of the route's actual segment of the URL. Think of the<route_key>
as an alias for the route. For example, in a routes key-value pair like this:"repos": "username?tab=repositories"
- therepos
is what's provided to theroute
option, while theusername?tab=repositories
is what's actually used to build the web query URL.
-
interface Engines {
[engineKey: string]: {
name: string;
url: string;
query?: string;
delimiter?: string;
isDefault?: boolean;
alias?: string | string[];
routes?: Routes;
};
}
interface Routes {
[routeKey: string]: string;
}
{
"google": {
"name": "Google",
"url": "google.com",
"query": "search?q="
},
"duckduckgo": {
"name": "DuckDuckGo",
"url": "duckduckgo.com",
"query": "?q=",
"delimiter": "+",
"alias": ["duck", "ddg"]
},
"youtube": {
"name": "YouTube",
"url": "youtube.com",
"query": "results?search_query=",
"delimiter": "+",
"alias": ["y", "yt"]
},
"mdn": {
"name": "MDN",
"url": "developer.mozilla.org",
"query": "search?q=",
"alias": "m"
},
"github": {
"name": "Github",
"url": "github.com",
"query": "search?q=",
"alias": ["git", "gh"],
"routes": {
"repos": "username?tab=repositories",
"stars": "username?tab=stars"
}
}
}
When browsers and engines config files are set up, certain keys and alias values automatically become flags. You can use these custom flags as substitutes for browser
, profile
, and engine
options.
For example, the following command with value options
web --browser=chrome --profile=dev --engine=mdn
can be re-written using custom flags:
web --chrome --dev --mdn
If a custom flag conflicts with a query option or its alias, the query option takes precedence.
The following config items are used to create custom flags:
keys | alias values | 1-letter alias values | |
---|---|---|---|
browser | ✅ | ✅ | ✅ |
profile | ✅ | ✅ | ❌ |
engine | ✅ | ✅ | ✅ |
Let's say we have the following browsers config:
{
"chrome": {
"alias": "c",
"profiles": {
"dev": {
"directory": "Profile 1",
"alias": "d"
},
"personal": {
"directory": "Profile 2",
"alias": "p"
}
}
},
"edge": {
"alias": "e",
"profiles": {
"dev": {
"directory": "Profile 1",
"alias": "d"
},
"school": {
"directory": "Profile 2",
"alias": ["s", "study"]
}
}
},
"firefox": {
"alias": ["f", "ff", "fox"]
}
}
These items from the above config can be used as custom flags:
keys | alias values | |
---|---|---|
browser |
chrome edge firefox
|
c f ff fox
|
profile |
dev personal school
|
study |
💡 Notice that the browser alias e
cannot be used as a custom flag because it conflicts with the alias of the engine
option.
Here's an example of an engines config:
{
"google": {
"name": "Google",
"url": "google.com",
"query": "search?q=",
"alias": "g"
},
"duckduckgo": {
"name": "DuckDuckGo",
"url": "duckduckgo.com",
"query": "?q=",
"delimiter": "+",
"alias": ["duck", "ddg"]
},
"youtube": {
"name": "YouTube",
"url": "youtube.com",
"query": "results?search_query=",
"delimiter": "+",
"alias": ["y", "yt"]
},
"mdn": {
"name": "MDN",
"url": "developer.mozilla.org",
"query": "search?q=",
"alias": "m"
},
"reddit": {
"name": "Reddit",
"url": "reddit.com",
"query": "search?q=",
"alias": "r"
}
}
The following items from the above config can be used as custom flags:
keys | alias values |
---|---|
google duckduckgo youtube mdn
|
g duck ddg y yt m
|
💡 Notice that the engine alias r
cannot be used as a custom flag because it conflicts with the alias of the route
option.