Can I keep my app proprietary? (a license checker)

4 minute read Published: 2025-06-21

You have hundreds of dependencies. Can you legally keep your app proprietary? Let's find out in 15 lines of Prolog.

Table of Contents

Disclaimer

This is a simplified model, for fun. Real license compatibility is complex and varies by jurisdiction. This is not legal advice. When in doubt, consult a lawyer.

The hidden problem

Your Node.js project probably has 500+ dependencies. Each has a license. Some of those licenses say "if you use me, you can't keep your software proprietary."

Most developers discover this too late.

Three licenses that matter

For 90% of cases, you only need to understand three licenses:

That last one is the killer. GPL is "viral" – if you use GPL code and distribute your software, your entire project must also be GPL. This "infection" spreads through your dependency tree. One GPL library deep in your dependencies can block you from keeping your software proprietary.

The term "viral" captures how GPL's requirements propagate: just like a virus, it spreads from the infected library up through all the code that depends on it.

GPL's "virality" is complex. Even Linus Torvalds admits there are "gray areas" in what constitutes a derived work. Static vs dynamic linking matters. SaaS is different from distributed software. But for this simplified model, we'll treat it as universally contagious.

Why most tools fail

License checkers typically scan your direct dependencies. But what about the dependencies of your dependencies? A seemingly innocent MIT library might depend on a GPL library three levels deep.

You need a lawyer. Call Prolog.

The 15-line solution

% Define which licenses are viral (they "infect" the whole project)
viral(gpl).

% Define compatibility (who can include whom)
compatible(mit, mit).
compatible(apache, mit).
compatible(apache, apache).
compatible(gpl, _).  % GPL can include anything

% Your app's dependency tree (declare as dynamic so we can modify)
:- dynamic uses/3.

uses(myapp, react, mit).
uses(myapp, tensorflow, apache).
uses(tensorflow, helper_lib, gpl).  % Ouch!

% Find viral infections recursively
% A project is "infected" if it uses GPL directly or indirectly
infected(Project) :- 
    uses(Project, _, License), viral(License).  % Direct GPL dependency
infected(Project) :- 
    uses(Project, Dep, _), infected(Dep).       % Transitive GPL dependency

% The key question: Can we keep it proprietary?
% Only if we're NOT infected by a viral license
can_be_proprietary(Project) :- \+ infected(Project).

That's it. The entire license compatibility checker.

Well, sort of. This simplified model captures the basic idea, but real license compatibility has dozens of edge cases. GPL2 vs GPL3? LGPL's linking exceptions? Apache's patent clauses? Dual licensing? We're ignoring all that to show the core concept.

See it in action

?- can_be_proprietary(myapp).
false.

Why? Let's trace the infection:

?- infected(myapp).
true.

?- uses(myapp, What, _), infected(What).
What = tensorflow.

So tensorflow is infected. Why?

?- uses(tensorflow, What, License), viral(License).
What = helper_lib,
License = gpl.

There it is. Your app → TensorFlow → helper_lib (GPL). You can't distribute your app as proprietary software.

(In reality: Maybe you can. Are you distributing the software or running it as a service? Are you linking statically or dynamically? Is there a GPL exception clause? These questions matter legally but not for our simple model.)

Fix it

What if we replace that GPL library?

?- retract(uses(tensorflow, helper_lib, gpl)),
   assertz(uses(tensorflow, helper_lib, mit)),
   can_be_proprietary(myapp).
true.

By swapping one dependency, we changed the entire legal status of our project.

Of course, in practice you'd need to ensure the replacement library actually does what you need, has compatible APIs, and doesn't introduce new issues. But the legal principle holds.

The clever part

Notice what we didn't write:

We just stated facts and rules. Prolog figures out the implications.

You can ask questions we didn't explicitly program:

% What's infected in my project?
?- infected(What).

% What licenses am I using?
?- uses(_, _, License).

% What depends on GPL code?
?- uses(What, _, gpl).

Why this matters

In 2004, the XFree86 project added an advertising clause to their license. It made them incompatible with GPL. The entire project died as developers fled to X.org.

MongoDB created SSPL because companies were reselling their database as a service. Now many organizations ban SSPL dependencies entirely.

These aren't edge cases. License incompatibility kills projects.

Try it yourself

The code above is a simple license checker. You can run it here or expand it to handle your specific needs:

Next time you npm install, remember: you're not just adding code. You're adding legal constraints.

Important: This post demonstrates a concept, not a complete solution. Real license analysis should consider:

The reality is that license compatibility often comes down to interpretation and intent, not just mechanical rules. When it matters (and it often does), get real legal advice.

References

The viral nature of GPL is well-documented but often misunderstood. See the FSF's GPL FAQ for authoritative answers.