Do you think its still worth to make this kind of parameter grouping
once the normal res.render!(templ, a, b, c, d) is used instead of
renderCompat?

Since the parameters of a template are effectively defined by the
template just like they are defined for a function, I thought that
direct passing of them was ok. Or, better put, to me the tradeoff
between understandability and terseness of the code is slightly in favor
of explicit parameter passing.

...but to be more constructive - with DMD 2.060 the following simple (*)
scheme without Variant should also work:

import vibe.d;

// inject library:
template injectReverse(Injectors...)
{

alias Injectors[0] First;
alias Injectors[1 .. $] Rest;
alias First!(Rest) injectReverse;

}
void reqInjector(alias Next, Vars...)(HttpServerRequest req,

HttpServerResponse res)

{

Next!(Vars, req)(req, res);

}
@property auto inject(alias Page, Injectors...)()
{

return &injectReverse!(Injectors, reqInjector, Page);

}

// application:
void authInjector(alias Next, Vars...)(HttpServerRequest req,

HttpServerResponse res)

{

string userinfo;
Next!(Vars, userinfo)(req, res);

}

void somethingInjector(alias Next, Vars...)(HttpServerRequest req,

HttpServerResponse res)

{

string something_else;
Next!(Vars, something_else)(req, res);

}

void page(VARS...)(HttpServerRequest req, HttpServerResponse res)
{

res.render!("upload_form.dt", VARS);

}

static this()
{

listenHttp(new HttpServerSettings, inject!(page, authInjector, 

somethingInjector));
}

(*) Actually this template stuff regularily makes my brain hurt...