# MTK & library components - good practice?

**URL:** <https://discourse.julialang.org/t/mtk-library-components-good-practice/135448>\
**Category:** Modelling & Simulations\
**Created:** [February 4, 2026, 1:36pm UTC](https://discourse.julialang.org/t/mtk-library-components-good-practice/135448 "2026-02-04T13:36:46Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [February 4, 2026, 1:36pm UTC](https://discourse.julialang.org/t/mtk-library-components-good-practice/135448/1 "2026-02-04T13:36:46Z")

</div>

I’m curious: what is good practice with MTK components which uses `Stream` variables/has multiple substances?

- How to ensure that the various components are created/instantiated with equal number of substances, so that I avoid connecting components that are not compatible?

Let me be concrete. I have the following connector using `Ns` – the number of substances (not meant to be professional; I am trying to learn things):

```julia
@connector function FluidPort(; name, Ns=1)
    vars = @variables begin 
        p(t), [guess = 0.0, description="Pressure, Pa"]
        md(t), [connect = Flow, guess = 0.0, description="Mass flow, kg/s"]
        x(t)[1:Ns], [connect = Stream, guess = 1/Ns, description="Mass fractions, -"]
    end
    System(Equation[], t, vars, []; name = name)
end

```

Next, consider two example components: first a “pump” where I need to specify the mass fraction composition (`x_set`). Since this must contain the number of substances, it feels redundant to also pass the number of substances `Ns`.

```julia
@component function PumpFixed(; name, md_set=1.0, x_set=[1])
    Ns = length(x_set)
    @named a = FluidPort(Ns=Ns)

    pars = @parameters begin
        md = md_set, [unit=u"kg/s", description = "Specified mass flow rate"]
        x[1:Ns] = x_set,[unit = u"kg/kg", description = "Specified mass fractions"]
    end

    eqs = [
        # Inflow to system means outflow from component (negative md)
        a.md ~ -md,
        # Define the stream variables for the port
        a.x ~ x
    ]

    compose(System(eqs, t, [], pars; name = name), a)
end

```

Next, a component that does _not_ need the mass fractions (they are not used):

```julia
@component function Plug(; name, Ns=1)
    @named a = FluidPort(Ns=Ns)
    # Hardcoded defaults are fine because md=0 makes x irrelevant to the system
    pars = @parameters begin
        x[1:Ns] = ones(Ns) ./ Ns
    end
    eqs = [
        a.md ~ 0.0, # Zero flow: mathematically plugs the port
        a.x ~ x, # Satisfies the stream contract
    ]
    compose(System(eqs, t, [], pars; name = name), a)
end

```

I have several other components, some where I specify `Ns` in the creation process, others where I specify the mass fraction composition vector (`x_set`).

My question is whether this is an OK practice, or whether there is a better practice. The way I do it, it is up to the user to make sure that the various components that are created and connected, are compatible. Which leads to some possibility of buggy system creation.
