I feel for a smallish project I'd rather prefer to have more readable, dense code like Ruby's over the ceremony of static types.

There is almost no ceremony involved in dealing with types in Rust.

And what little there is, is worth it ten-fold for all of the runtime bug headaches that you avoid compared to dynamically typed languages.

Specifically addressing the "almost no ceremony" claim and not the "totally worth it" claim:

JS:

  let person_1 = { };
  let person_2 = { parent: person_1 };
  person_1.child = person_2;
Rust:

  use std::cell::Cell;
  struct Person<'a> {
      parent: Option<&'a Person<'a>>,
      child: Cell<Option<&'a Person<'a>>>
  }

  let person_1 = Person {
      parent: None,
      child: Cell::new(None)
  };
    
  let person_2 = Person {
      parent: Some(&person_1),
      child: Cell::new(None)
  };
    
  person_1.child.set(Some(&person_2));
And that's before we start talking about function signatures and traits.