# Command line in web.
**Clap in web.**
Pronounced "Clue" as in "Get a cliw."
Command line arguments for native and the web.
\
Also provide output for the web.
The goal is to be flexible, write your command line code once and it should be able to run anywhere!
<a href="https://github.com/stonerfish/cliw_examples/we-clap_demos/we-clap_egui_demo"><figure><img alt="Screencast of an egui app running in web page with popup alerts showing a variety of clap help messages." src="https://github.com/stonerfish/cliw_examples/blob/master/we-clap_demos/we-clap_egui_demo/we-clap_egui_demo.gif?raw=true" width="50%"><figcaption>we-clap_egui_demo</figcaption></figure></a>
## Why use cliw?
You probably don't want to use [`cliw`] directly. This crate was designed so [`clap`] can be
used in the web. You normaly [`use cliw indirectly`] with a web enabled clap, [`we-clap`].
Find cliw at [`crates.io`], or the [`cliw repository`].
Also check out the [`examples`] and [`docs`].
## Why not use cliw?
* If you are writing only for the web, you may not be wanting to use command line arguments.
* You might have another use of the url query string.
* You might be compiling to wasm but the framework you use provides [`std::env::args_os`]
and/or standard output.
## Recommended usage
Cliw was designed to enable clap to be used in the web. The best way to use cliw is to use
a web enable clap [`we-clap`] and pretend like you are just using clap. [`we-clap_demo`].
Cliw can also be used with a regular clap. You just need to do a little more work. [`cliw_clap_demo`]
Of course cliw can be also used for getting args without using clap. [`cliw_demo`]
### we-clap_demo
#### Web enabled clap features
The patches to clap, [`we-clap`], are minimal and try to be non-invasive.\
The wasm/web enabled we-clap functionality is gated by features.
* unstable-web-alert
- Enable we-clap to use an alert for its output on the web.
- we-clap will have cliw as a dependency with the "alert" feature set
* unstable-web-console
- Enable we-clap to use the browser console for its output on the web.
- we-clap will have cliw as a dependency with the "console" feature set
* unstable-web-urlargs
- Enable we-clap to use urlargs on the web.
- we-clap will have cliw as a dependency with the "urlargs" feature set
#### Cargo.toml
``` toml
[package]
name = "we-clap_demo"
version = "0.1.0"
edition = "2021"
[dependencies]
# use a web enabled version of clap
clap = { git = "https://github.com/stonerfish/clap", branch = "we-clap", features = [
"derive", #normal clap derive feature
"unstable-web-alert", #enable clap to use an alert for its output on the web
"unstable-web-urlargs" #enable clap to use urlargs on the web
] }
```
#### main.rs
``` rust
use clap::Parser;
#[derive(Parser, Debug, Default)]
#[command(author, version, about, long_about)]
pub struct Opts {
/// A required string
#[arg(short, long)]
pub words: String,
/// An optional value
#[arg(short, long)]
pub value: Option<f32>,
}
fn main() {
// Like magic, this will work on native parsing the command line arguments,
// or on the web parsing the url query string as if it were command line arguments,
// providing clap help and error messages to stdout/stderr on native or a popup alert on web/wasm.
let opts = Opts::parse();
// this app doesn't do anything, except parse arguments and demonstrate clap powers in the web.
}
```
#### Running with wasm-server-runner.
``` console
cargo r --target wasm32-unknown-unknown
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.06s
Running `wasm-server-runner /path/to/target/wasm32-unknown-unknown/debug/we-clap_demo.wasm`
INFO wasm_server_runner: uncompressed wasm output is 2.10mb in size
INFO wasm_server_runner: starting webserver at http://127.0.0.1:1334
```
<a href="https://github.com/stonerfish/cliw_examples/we-clap_demos/we-clap_demo"><figure><img alt="Screencast of the we-clap_demo program running in web page with popup alerts showing a variety of clap help messages." src="https://github.com/stonerfish/cliw_examples/blob/master/we-clap_demos/we-clap_demo/we-clap_demo.gif?raw=true" width="50%"><figcaption>we-clap_demo</figcaption></figure></a>
### cliw_clap_demo
If you don't want to use a web-enabled clap you can use cliw with regular clap, but it is a little bit
more work. You use the clap functions "try_get_matches_from()" or "try_parse_from()" passing in
cliw::args_os() as the iterator. For output we use cliw, but for the clap error output on native we use
the clap error print() method so that colors and stdout/stderr work properly.
#### Cargo.toml
``` toml
[package]
name = "cliw_clap_demo"
version = "0.1.0"
edition = "2021"
[dependencies]
# use a regular (non-web enabled) version of clap
clap = { version = "what", features = [
"derive",
] }
cliw = { version = "0.1.0" , features = [
"alert",
"urlargs",
] }
```
#### src/main.rs
``` rust
use clap::Parser;
#[derive(Parser, Debug, Default)]
#[command(author, version, about, long_about)]
pub struct Opts {
/// A required string
#[arg(short, long)]
pub words: String,
/// An optional value
#[arg(short, long)]
pub value: Option<f32>,
}
fn main() {
// Try parsing ArgsOs on native or UrlArgs on wasm/web
let opts = Opts::try_parse_from(cliw::args_os());
// Handle the result
match opts {
Ok(opts) => {
let msg = format!("{opts:?}");
println!("{msg}");
cliw::output::print(&msg);
}
Err(err) => {
// jump through some hoops to get proper color and error direction on native
#[cfg(not(target_arch = "wasm32"))]
{
err.print().unwrap();
}
// and this hoop to get output for web/wasm
#[cfg(target_arch = "wasm32")]
{
let msg = format!("{err}");
cliw::output::eprint(&msg);
}
}
};
}
```
#### Running with wasm-server-runner.
``` console
cargo r --target wasm32-unknown-unknown
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.06s
Running `wasm-server-runner /path/to/target/wasm32-unknown-unknown/debug/cliw_clap_demo.wasm`
INFO wasm_server_runner: uncompressed wasm output is 2.10mb in size
INFO wasm_server_runner: starting webserver at http://127.0.0.1:1334
```
<a href="https://github.com/stonerfish/cliw_examples/cliw_clap_demos/cliw_clap_demo"><figure><img alt="Screencast of the cliw_clap_demo program running in web page with popup alerts showing a variety of clap help messages." src="https://github.com/stonerfish/cliw_examples/blob/master/cliw_clap_demos/cliw_clap_demo/cliw_clap_demo.gif?raw=true" width="50%"><figcaption>we-clap_demo</figcaption></figure></a>
### cliw_demo
If you don't want to use clap you can use cliw and just process the args yourself.
#### Cargo.toml
``` toml
[package]
name = "cliw_demo"
version = "0.1.0"
edition = "2021"
[dependencies]
cliw = { version = "0.1.0", features = [
"alert",
"urlargs",
] }
```
#### main.rs
``` rust
fn main() {
// This is an example using raw cliw without using clap
let args = cliw::args_os();
let args: Vec<_> = args.collect();
let msg = format!("{:?}", args);
cliw::output::print(&msg);
}
```
#### Running with wasm-server-runner.
``` console
cargo r --target wasm32-unknown-unknown
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.06s
Running `wasm-server-runner /path/to/target/wasm32-unknown-unknown/debug/cliw_demo.wasm`
INFO wasm_server_runner: uncompressed wasm output is 2.10mb in size
INFO wasm_server_runner: starting webserver at http://127.0.0.1:1334
```
<a href="https://github.com/stonerfish/cliw_examples/cliw_demo"><figure><img alt="Screencast of the cliw_demo program running in web page with popup alerts showing a variety of clap help messages." src="https://github.com/stonerfish/cliw_examples/blob/master/cliw_demo/cliw_demo.gif?raw=true" width="50%"><figcaption>we-clap_demo</figcaption></figure></a>
## Cliw Features
The functionality of the cliw crate is gated by features.
* alert
- Enable output to browser popup alert.
* console
- Enable output to browser console.
* web-std-output
- Enable standard output on the web.
- You can use this if your web framework provides standard output.
- You always get standard output on native.
* urlarg
- Enable getting args from [`UrlArgs`] on the web.
- Do not use this if your web framework provides [`std::env::args_os`].
For simplicity just set the "urlargs" and "console" or "alert" features in you Cargo.toml for
both native and wasm. Under native you always get standard args and output.
```toml
cliw = { "0.1.0", features = [
"alert",
"urlargs",
]}
```
## License
Copyright 2025 Richard Gould
Licensed under either of
* Apache License, Version 2.0
([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license
([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
## Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.
[`clap`]: https://crates.io/crates/clap
[`cliw`]: https://crates.io/crates/cliw
[`cliw_clap_demo`]: https://github.com/stonerfish/cliw_examples/cliw_clap_demos/cliw_clap_demo
[`cliw_demo`]: https://github.com/stonerfish/cliw_examples/cliw_demo
[`cliw repository`]: https://github.com/stonerfish/cliw
[`crates.io`]: http://crates.io/crates/cliw
[`docs`]: https://docs.rs/cliw
[`examples`]: https://github.com/stonerfish/cliw_examples
[`std::env::args_os`]: https://doc.rust-lang.org/std/env/fn.args_os.html
[`UrlArgs`]: https://docs.rs/cliw/latest/cliw/urlargs/struct.UrlArgs.html
[`use cliw indirectly`]: https://github.com/stonerfish/cliw_examples/we-clap_demos/we-clap_demo
[`we-clap`]: https://github.com/stonerfish/clap/tree/we-clap
[`we-clap_demo`]: https://github.com/stonerfish/cliw_examples/we-clap_demos/we-clap_demo