# Package development workflow

**URL:** <https://users.rust-lang.org/t/package-development-workflow/107399>\
**Category:** help\
**Created:** [February 26, 2024, 4:57pm UTC](https://users.rust-lang.org/t/package-development-workflow/107399 "2024-02-26T16:57:58Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![cscherrer](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/cscherrer/32/36694_2.png) [@cscherrer](https://users.rust-lang.org/u/cscherrer)\
**Post date:** [February 26, 2024, 4:57pm UTC](https://users.rust-lang.org/t/package-development-workflow/107399/1 "2024-02-26T16:57:58Z")

</div>

Hi 👋

For package development in Haskell or Julia, I really like the workflow of starting with a simple version of the package I want to implement, and then exploring it in the REPL. GHCi and the Juila REPL are both great in terms of auto-reload, tab completion, and generally exploring code functionality.

In Rust, I've tried [evcxr](https://github.com/evcxr/evcxr) for this, and so far it's just not as smooth as the others. I don't know how much of this is because I'm not using it right, or because it's still pretty young, or because (maybe?) Rust just doesn't lend itself to this approach.

I'd appreciate any advice on

1. If there's a better way to setup or use evcxr for this, or
2. If there are better REPLs out there for this, or
3. If there's a better development workflow that can give a similar advantage in terms of, I don't know, let's call it "immersiveness"

Thanks,  
Chad

---

<div class="post-metadata">

**Author:** ![kpreid](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/kpreid/32/22420_2.png) [@kpreid](https://users.rust-lang.org/u/kpreid)\
**Post date:** [February 26, 2024, 5:28pm UTC](https://users.rust-lang.org/t/package-development-workflow/107399/2 "2024-02-26T17:28:30Z")

</div>

Personally, I prefer writing tests — create a `#[test]` function and write whatever code you want in it. With VS Code and rust-analyzer, you can use the “Rerun Last Task” command to save and run the code in one keystroke. You may be rerunning the code from the beginning, but that isn't worse in most exploratory cases, and it means that you can make an edit anywhere and see all of the consequences of it, rather than having stale results hanging around.

(And then once you're satisfied with the results, you could add an assertion and keep around the code as an actual test, if that makes sense.)

For large projects, I suggest placing the experimental test code in the “integration test” directory `tests/` so that the test is compiled separately from the library itself, so recompiling the test doesn't include recompiling the library code. (But this is probably unnecessary for a small, quickly compiling library.)

---

<div class="post-metadata">

**Author:** ![cscherrer](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/cscherrer/32/36694_2.png) [@cscherrer](https://users.rust-lang.org/u/cscherrer)\
**Post date:** [February 27, 2024, 2:51am UTC](https://users.rust-lang.org/t/package-development-workflow/107399/3 "2024-02-27T02:51:31Z")

</div>

Thanks @kpreid. I like the idea of using tests like this. It seems trickier to get intermediate results printed, since stdout is redirected by default, so there are some tradeoffs there. I also hadn't thought about `tests/` allowing separate compilation, that's a great point.

After I posted the OP here I was also chatting with @miguelraz . From that discussion the `cargo run --example foobar` idiom also seems very useful.

I think I'll still miss REPLing for at least a while, but between this and tools like Rust analyzer, bacon, and clippy, maybe the feel can get pretty close.

Thanks again 🙂

---

<div class="post-metadata">

**Author:** ![miguelraz](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/miguelraz/32/12967_2.png) [@miguelraz](https://users.rust-lang.org/u/miguelraz)\
**Post date:** [February 27, 2024, 3:05am UTC](https://users.rust-lang.org/t/package-development-workflow/107399/4 "2024-02-27T03:05:49Z")

</div>

To add to kpreid's point above, check out the incredibly useful [debug\_assert!](https://doc.rust-lang.org/stable/std/macro.debug_assert.html) macro which will run in `debug` mode but be optimized away in `release` mode.

But yes, if anyone has a REPL-y style workflow in Rust, I'm all ears, as I've gone into quite detail of the UX in Julia Land

[![](https://img.youtube.com/vi/bHLXEUt5KLc/maxresdefault.jpg "Julia REPL Mastery Workshop | Miguel Raz Guzmán Macedo | JuliaCon 2022") ](https://www.youtube.com/watch?v=bHLXEUt5KLc&t=2s)

---

<div class="post-metadata">

**Author:** ![jumpnbrownweasel](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/jumpnbrownweasel/32/17403_2.png) [@jumpnbrownweasel](https://users.rust-lang.org/u/jumpnbrownweasel)\
**Post date:** [February 27, 2024, 4:19am UTC](https://users.rust-lang.org/t/package-development-workflow/107399/5 "2024-02-27T04:19:33Z")

</div>

> [@miguelraz](#):
>
> check out the incredibly useful [debug\_assert!](https://doc.rust-lang.org/stable/std/macro.debug_assert.html) macro

Even more useful for ad hoc exploration is the [dbg!](https://doc.rust-lang.org/std/macro.dbg.html) macro. It prints its arg list as nicely as any repl I've used. (Of course, a repl does it without a build step.)

Not mentioned yet are the IDEs (including any editor with LSP support) that let you look at the type of a variable you hover on, drill down into source code for the selected symbol, etc. This is only static exploration, not runtime exploration, but it has gotten very good.

---

<div class="post-metadata">

**Author:** ![kpreid](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/kpreid/32/22420_2.png) [@kpreid](https://users.rust-lang.org/u/kpreid)\
**Post date:** [February 27, 2024, 4:20am UTC](https://users.rust-lang.org/t/package-development-workflow/107399/6 "2024-02-27T04:20:58Z")

</div>

> [@cscherrer](#):
>
> It seems trickier to get intermediate results printed, since stdout is redirected by default,

Passing `--show-output` or `--nocapture` to the test harness (`cargo test -- --show-output`) will let the output be seen even if the test passes, and rust-analyzer passes `--nocapture` by default for all test runs ([though I think it really shouldn't](https://github.com/rust-lang/rust-analyzer/issues/12737)).

(Also, the redirection is actually not stdout, but a Rust `std`-specific mechanism that applies only to `println!`, `eprintln!`, `dbg!`, etc. — so you can actually bypass it by writing to `std::io::stdout` or `stderr` directly. But that's not particularly friendly to exploratory programming.)

---

<div class="post-metadata">

**Author:** ![system](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/system/32/51372_2.png) [@system](https://users.rust-lang.org/u/system)\
**Post date:** [May 27, 2024, 4:21am UTC](https://users.rust-lang.org/t/package-development-workflow/107399/7 "2024-05-27T04:21:51Z")

</div>

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.
