Transcript
This transcript was autogenerated. To make changes, submit a PR.
Hello everyone, and welcome to how the magic of open source helps
our project. My name is Daniel Espino Garcia.
I am a software design engineer at Mattermost. If you want
to contact me, feel free to drop by the office at Mattermost community
server. Before we start, let me tell
you a story. Imagine you are using a program.
You only have the binary, so you cannot look inside
and you want to know how it will behave.
The only way you can do that is by looking at the documentation
or experimenting. You could also try
stack overflow or Chat GPT to see if you
get the answer. But maybe your question
is so deep that they cannot answer it. Neither can
experimentation can give you an idea,
but you cannot know for sure. Wouldn't it be great
if you could see how the program was made?
If you could look beyond the black box and tap
into the essence of the program, wouldn't that be like
magic? Ladies and gentlemen, that is
part of the magic of open source. Here is the
agenda for today, and without further ado, let's start
what is open source? Let's start with
a few misconceptions. The first misconception
is about the word free. Sure, most of
the open source code that is out there you can get for free.
But the free world is about freedom,
not about the cost. If we go to the open source initiative
definition, the main part of the freedom is
the freedom to redistribute the code, not about
that being free. Another common misconception
is that open source community can
be your free labor. They will test
and contribute to your project, and you don't have to pay them anything
because that's how open source works.
No, that may happen,
but it's not how it works. You need to have a good
product or library. People have to find it,
people have to use it, and people have to see potential in
it. So it's worth the time contributing.
And all that is not free.
And when you get to the point where they start contributing,
you still have to keep control of your library.
Review the pull request, discuss the changes. Sure it
helps, but it's not free. Next you
could ask, how can you sell something that is free?
Well, there are many ways. Among other things, it's not
only the code that you are selling, it's the whole
product or sometimes a service.
There are out there big profitable companies that are open source,
like red hat. Others like GitHub use an
open code approach that I will talk about later.
And other huge companies like Meta or Microsoft
have a big part of their code, also distributed as open
source. So looking at examples,
yeah, it seems that it is economically
viable. Finally, some people
will say that open source is a niche,
something just a few people use.
But according to some sources, 90% of
the code you have out there uses open source
one way or another. Sure, oftentimes it's
used to create proprietary code, but still use.
So not really a niche.
So yeah, we know everything that is
not open source, but what is open source?
I'm going with an adaptation of the open source initiative definition.
What I feel is more important are these points.
First of all, the code of the software has to be available.
You must be able to look at the code of what you
are executing. Next is derived workers.
The license must allow creating derivative work out of
the code and distribution under the same license.
This can be under different restrictions based on the license, but in
general it's about being able to use the open source code in the
project. Another important one is that the
distribution should not discriminate. Everyone should
be able to use the code in any field and with
whatever technology. And finally one
that is really useful for us everyday developers.
Free redistribution people redistribute
the code as a gregate of programs.
That is what bring us tools like NPM to us.
But what kind of open source exists out there?
One way to look at it is about openness. The most
pure way of open source is that open
source, what we have already talked about. Then you
have Opencore, which is a mix of open and closed source.
The code of the product must be usable as a standalone
and be open source. The rest of the add OSS
may be closed code. With that in mind, you could differentiate
between open core with a thick closed layer and open
core with a thin closed layer. For example, as in mattermost,
I will say that more than 90% of the code is
open source with a thin layer of closed code.
Apart of that, you may have code available that
is not really open source because the license on top of
this code forbids the use and distribution of
the code. But you are able to look at it making
the code visible, which is also really interesting.
Then you can look at the licenses. Regarding licenses,
there are tons of different licenses,
each one with some kirks. For example,
the GPL license force that any derivative work
must be released as a GPL license.
The BSD one allows you to modify and distribute the
software as long as you keep a copy of the original copyright
notice. List of conditions and disclaimers finally,
the MIT one is one of the most lags,
allowing you to do all the changes you need as long
as you keep a copy of the original license and
copyright notice. Well,
now that the history lesson is over,
let's get down to business. Open source
is great, and it will be great to use it on our project.
But how do we do that? Do we have to go to
every GitHub repository and download it?
Kinda, but not really. That is where package
managers come into place. There are out there many repositories
of open source libraries. Each language has their own,
but I'm going to talk about one we use at mattermost NPM.
NPM stands for node package manager,
but as they say on their website, it's not only
that, it also has a registry of open source packages to
use on your apps. And finally, it is also a
command line client to use or publish those packages.
NPM tracks all your dependencies and
helps you install all the different things you need to make your code work.
And where does it all go? To the node modules folder.
Every single package you need, including their dependencies,
will be downloaded and throw into the node modules
folder. This you see in the slide.
This is part of the contents of the node modules folder in
our mobile app. It is overwhelming the
amount of code we are using that we didn't write ourselves,
and all this code will be compiled and sent
over with our application without any cost.
And part of that is thanks to the concept
of open source software.
But what is inside this?
Let's take a deeper look at the library. At one library, for example,
the base 64 package, as you can see
there we have the full code for us to
see. And here is where the magic of open
source I was talking about starts to happen.
So we have all that code there and
how can we use it? Understanding what
happens beneath for this section, I want to put you into a real example.
At some point we noticed our app was mixing
images. It didn't happen often, so it was really hard to
reproduce, but we were able to pinpoint the issue down
to one of our direct appendices. Fuzzimage.
But more interestingly, it only happened on iOS.
If this was closed code, we may be able to use
a binary of fastimage libraries in our code,
and when we face this problem, our only choice will
be to send an email complaining how their library is
causing problems. But with open source we are
able to get a bit deeper. When we get
to the node modules folder of the fast image libraries,
we see this. The JavaScript side
mainly uses the native component and since our
code only fails in iOS, it makes a lot of
sense or problems over there. But when we go
to the native code we see this fastimage
is implementing an element from another libraries
sd animated image view. So we
found our problem was not directly related to fastimage,
but an underlying library. We were able to go even
farther down looking at the code of this library and
well yeah, we didn't fix the issue,
but we were able to post in their repo
about this problem. And a few versions later the
issue was fixed and ready for
use in the newest version.
But it's not only about tracking
bugs. Sometimes yes, you want to learn more.
For example, should you flatten your styles before
passing them to components in React native? The only
way to know that is to see the underlying implementation.
This is not something you can do with closed code,
but here it's way simpler.
We go to the library and see how things are done under the
hood. In this particular case we see that all
basic components in react native are calling fluttering
style either way, so calling
it ourselves helps at apparently nothing.
Sometimes the libraries are distributed in a minimized way,
making it really difficult to understand what is going on.
Let's imagine we want to check how expensive is
using a use memo in our components.
We want to get some extra performance, but will
use memo really help and at what cost.
So we dive into the code modules files of
react and we find, among other things,
this okay yeah,
as you can see, hard to see what is
going on here, but do not fear.
What we can do is go to the actual code.
How we do this, probably a Google search will
take us where we want to go faster, but let's do it the
long way. First of all, let's go to
RPM and look for the package. Yeah, the package
we're using is react. So there
you have the repository link,
let's go to the repository and voila.
All the react code at the tip of your hands.
After some more searching, making sure you are in the right branch
and so on and so forth, you may find this.
So the actual function I should be looking for
is update memo. And where is that? In my
code modules. Because I mean that
code is executing so it should be somewhere in my note
modules. Let's take a look.
There you are. Apparently react native will implement this
a little bit and looking a bit into it, you can start
grasping the overhead of using use memo, which well
in general is not much.
Well, learning is great, but at some point you
want to get things fixed. So what can
we do? Let's have some real examples about that.
What you see in the screen on the left side is
the comment history of the latest release version of
React Native realized library, one of the libraries we
use at Mattermost. And on the right you
can see the commit history of the main branch.
As you can see, a lot has happened since let's
imagine there's a bug that is affecting my application.
I need to fix it and I know the
bug is in the library, but great,
it is fixed on main but not on the latest
release. If this was closed code,
yeah, I wouldn't even know there's a fixing
in main. All I could do is complain
and hope that some point it will get fixed.
But since this is open source we
know there's a fix and that opens several options.
The easiest one is just wait for the new release,
but sometimes they're bugs more time sensitive.
You may have to align to your own release cycles or it is
affecting a critical part of your app.
Waiting is not always an option. Another option will
be to import the library directly from Main.
That is a bad idea. Depending on the
project, main may not be the best tested and stable branch.
You may be able to afford to add one commit that fixes
the problem you have, but do you want to include all other
changes that maybe create more trouble?
Probably not. One extra option is
to create your own fork and cherry pick the change.
Then you just have to import your fork and that's it.
But then it makes more complicated to keep
the track of the new versions because yeah, a new version
appears on the main repo so you have to sync
your fork or yeah,
you no longer need a fork, so you change back
the reference to import the original library,
but then you want to add another fix so you get back to your fork.
Yeah, that seems a lot of work. The option I like the most
is patching the package. Let's take an example
again the mixed image problem.
I told you that one more recent version of the under lighting library,
the issue was fixed, but what
we are using is the fast image library.
We will need to get that updated too. But no,
it's not needed. If we patch the library,
we just need to find the correct files in the node code folder. For example
this one where you see that we
are setting the library version, make the changes we need
and run Npxpx patch package that
will create a new patch with the changes that
will be used every time I install the library.
As you can see on the left, this is something we sensitively
do in our project, but patches have
one more use changing how things work.
Libraries are great, but sometimes you want them to work in
a slight different manner. You want that tweak
that things that make them more yours.
Again with close code, all you could do
is complain and hope. And if what you needed
is something only you need, you can expect the original
developer to add it. So you may
end up creating your own library just because you needed
that small thing, but not with open source.
Let me give you an example. React native hat
feedback library as you can see here, the different
type of vibrations are hard coded. Probably there
are good reasons for that. But we want a
vibration that has a special duration and
how we do that. We could rebuild
the whole library ourselves so we can have
the durations the way we want them. We could create
a fork and do that in our fork.
Or we can even ask the original developer to comply with
our needs and do the things we need.
But yeah, all that seems kind of wrong.
Let's just patch it. The process is the same as
with the fixes. You modify the file in your non modules
folder, call NPX patch package and
there you have the patch to use the library
as you need. Let's look at another example.
We use Watermelon DB library as an alternative to redux to
store the state of the app. Watermelon Db uses
an underlying SQL live database to store the state in
order to keep the data integrity. It has some checks as the following
you cannot batch elements without changes and you cannot update rows with
pending changes. This is really important
because if not, you may end up with unexpected results.
But we needed to go around those limitations.
We still want to inform the developer they are doing something out of the ordinary.
But if the developer knows what they are doing,
we want to allow it. But that is us.
Most people should still have those guards.
So again, what did we do? Ask the
developer to comply to our needs? No,
we just patched the package. We made
the changes we wanted, so the process continued the
way we thought it was the correct way. We keep it
contained so only us do this in the dangerous way and
we don't have to wait for the original library to get a new release out.
And well, we are almost at the end.
I hope you like this talk and you discover
a new phase of the magic of open source and start
using it to help your projects. But the reality
is that it's not only about the code.
That's not only where open source helps your project.
When you decide to become open source,
you open the door to a community,
people that will help your project to improve in many ways.
People not only contributing code directly.
For example, in Mattermost we have received tons of
localization contributions.
Also, being open source helps you
to achieve better security and security contributions.
For example, with hacker one bounty programs,
or even when a client wants to audit your code,
the security of your code, you can just
have it there, it's there, you can look at it and see how security
is or not. We also have a growing community of
QA contributors, and that helped a lot during
the last October fest. We also have the community server
where a lot of troubleshooting is done many times,
not even by members of the staff, but by peers helping each
other. And of course all the
people that find and report backs or propose new features.
As you can see, opening the code and opening
the door to the community can be a great boost
to your project. And if anyone from the
community is watching this talk, I want to say thank
you. Mattermost wouldn't be the same without you.
And another important thing in open source,
remember to give back. The simplest
thing you can do is open your code.
But yeah, I understand that's not always possible,
but if you are creating any library or
any tool that could be used for more people,
consider opening it. Usually that
is easier to open than the whole project,
and you may be able to help a lot of people out there. The next
best thing is to go out there
and contribute. Whenever you're using a library,
think how you can make it better and try to get
those improvements upstream. Your project will be
better since the library you're using is better,
and you will also make it better for
many more people. And if
you want to do still a bit more, feel free to donate money to different
projects. There are many open source projects out there accepting
donations and that is one way to keep the ball rolling for those projects.
And just to summarize what we talked today,
a few notes. Get comfortable with how
non modules is organized or well, if you are
using any other language. However, that language manages the packages.
Do not be afraid. In diving into library
code, it can help you understand better how things are done under the hood
and help you grow. As an engineer, remember that
you can fix libraries before the change gets upstream.
But of course, if you are the one fixing it,
be nice and create a pull request in the original library.
And last of all, remember that if you want a
different flavor in a libraries, you can always patch it so
it works the way you want. But yeah,
remember that you have patched. So when you face an
issue before creating the issue directly on the
repository of the creator make
sure you didn't introduce the issue with your patches s and
well, thank you very much for watching this talk.
I hope you like it. And if you want to
ask any questions or leave any comment, remember that you can do
it at the office at community mattermost.com.
Goodbye.