This sounds like the main methods i write (in Java, also not using a DI framework). Like this:
var database = new DatabaseFacade(config.get("db.host"), config.get("db.port", Integer::parseInt));
var users = new UserRepository(database);
var catalogue = new ProductRepository(database);
var cart = new ShoppingCartController(users, catalogue);
It's imperative code, of course, but it's sort of declarative in that all the code is doing is wiring things up. It's step-wise in that it does one simple thing after another; it might be quite long, as there are a lot of components to create, but it can be understood locally. Components are manually constructed, by calling constructors, rather than via reflection done by the framework. Components are passed to each other as parameters to establish dependencies, rather than there being some sort of rule-driven lookup, as a framework would do. It is indeed pretty tedious to read, as it's just lots of constructor calls, with no thrilling action. But it's so simple it's never confusing (and you get to use the full power of the IDE to navigate it, jumping to definitions and uses etc). And, as such, easy to maintain. Definitely refreshingly so if you've come from Spring or Guice.