I created a thread earlier this year to discuss exactly the same question, I think:
Simple and complex solutions have been proposed. My personal conclusion for now is that (1) there is a missing feature in the Typst language to better support this, and (2) in absence of proper support, the solution which I suspect scales best is to have the package return a dictionary of names (constants and functions), instead of defining toplevel constants and functions directly.
Instead of
#import "template.typ": *
.... #logo ... #coverimage ...
users would do
#import "template.typ": template
// template is a dictionary with fields `logo`, `coverimage` etc.
... #template.logo ... #template.coverimage
Then if you want to add global parameters to your package, you can export a function that returns a dictionary. So users now write as follows:
#import "template.typ": template
// template is a function that returns a dictionary
#let template = template(theme: "IKEA")
// shadow the name with an instantiated dictionary
... #template.logo ... #template.coverimage
The change from one version to the other is smooth for users (unlike moving from the constants-at-toplevel to the packed-in-a-dictionary style, which requires a global change), so if people consistently package their stuff in dictionaries they can smoothly add parameters or in general more flexibility.