Thank you.
Our next speaker is Victorien, who is one of the lead maintainers of the Bayonne open
source project.
Big round of applause for Victorien.
Hi everyone.
Is everyone heard me?
It's okay.
Is everyone heard me?
Yeah.
I'm Victorien and I'm one of the biome lead maintenance.
In this talk, I will present some unique characteristics of biome.
We take a high overview of its internal, how it achieves this kind of unique characteristics.
What is biome first?
Biome is a code linter.
Biome analyzes your code statically to find bugs to enforce convention with a team,
similar to ES lint.
Biome supports natively JavaScript, JavaScript, JS6, TS6.
Unlike ES lint, you don't need to install zillion of plugins.
You don't need extra dependencies or extra configuration to support TypeScript.
Biome also tries to output helpful diagnostics.
It brings you some context, explains the issue, and provides a course of action to solve the
issue.
For example, in the figure, you have a unique biome rule named no accumulating spread,
and they warn you against the use of accumulation of the spread operators in reduce and maps.
Biome currently provides 200 rules.
Some are unique to biome.
Overcome from ES lint, ES lint, TypeScript, and over plugins.
One of our contributors is currently working on Ter-Wine class sorting.
Biome is also a code formator.
You can format JavaScript, TypeScript, JS6, TS6, JSON, JSONC, and we are currently working on CSS formatting.
In contrast to Prettier, Biome is able to format invalid code, as demonstrated in the animation.
Last November, one of the mountaineers of Prettier launched 10,000 Bounty.
The goal was to create an alternative to Prettier, a faster alternative, right in the rest.
That matching the Prettier output, in particular for the JavaScript formator, over guys come in the play and add monies, reaching $25,000.
In one month, we made it.
We reached 97% of compatibility with the JavaScript formator, not only for JavaScript, but also for TypeScript, JS6, TS6, and JSON.
One question remains, is biome fast?
According to our users, it is.
Here we have an employee of OpenAI at TestBiome, and using biome to replace the S-Kint and Prettier, they reduce the linting and formatting time from one minute to about two seconds.
Biome is also a growing community.
We have, we reach 170,000 weekly downloads on NPM, and we have a big player that starts using biome.
We have Astro, we have Arespaq, it's a project from Baddance.
We have a three-person company, and we have a Gold Sponsor, Shiguredo, a Japanese company.
Now you are familiar with biome.
I propose you to take a look to its internal.
Biome uses a leader follower architecture.
We have a main thread, the leader thread.
The leader thread spawns a thread for each file to process.
This allows to scale with a number of threads on your computer.
Each thread parts the file in a structured form, a tree, and under the file, for example, formatting, linting, and so on.
Usually, code formators at Cundlinton in the JavaScript world keep every Watt space, every character.
And the very tolerant parser is able to represent missing pieces in the tree.
For example, here we have a hole because the variable is not initialized.
And we have also a bogus node in some other case.
And yes, we are able to format and fix the linting issue by replacing the bilete and removing the training space and indentation.
If I use less indentation.
That's fine.
Many rules are like no var or no accumulating spread directly query the concrete syntax tree to output diagnostics.
But sometimes you have some rule more complex.
For example, no unused variables in the following code.
The name variable in the conditional is unused.
For this kind of rule, it's very hard to implement the rule just using the concrete syntax tree.
In VatsCas, it's good to have extra information.
For example, it's under scope, lexical scope.
For example, you can see the name parameter is shadowed by the local variable name in the conditional.
And you have also to handle a listing issue with function var places.
To do so, instead of querying directly the tree, we consume the tree and provide the extra data in a semantic model.
The semantic model is able to answer questions like find me all references of such declaration.
And is this reference a right reference or read reference?
For example, in the previous example, the name is unused because it's only right.
It's not read.
In September, we have a first version of name resolver.
But a very simple name resolver.
The goal of a random resolver is to bind the declaration to the references.
Basically, this name resolver assigns a unique identifier for each declaration.
And they follow an invariant that is a reference refer to a single declaration.
You have some example here.
It's correctly under scope because the name parameter is linked to the parameter for the same for the return value.
And in the local variable case, it's also correctly bind.
The issue is this name resolver doesn't play well with TypeScript.
In fact, in TypeScript, you can use the same name for tip and variables.
For example, here you have an interface and function with the same name.
And using this first version of the name resolver, you can see some issues.
For example, the return tip person is bound to the function name.
And we export only reference the function.
Actually, a reference in TypeScript can reference several declaration.
Here, the export reference both the interface and the function.
And we have also two differences between tips and variables because the return tip references the type and not the function.
In fact, yes, maybe.
We can just conclude here that a reference can reference a variable, a tip, or both.
In fact, it's even worse than that because in TypeScript, a reference can reference an infinite number of declaration.
Here, you have an example of the E type, in fact, reference three in fair declaration.
You have also over issue, for example, in TypeScript, it's possible to partially reference a tip variable.
For example, a case, it's both a tip and a variable.
And here, you have the first reference only the variable and the last one, reference only the type.
So to support TypeScript, we don't want, in fact, to handle every edge cases because it's very complex to expose this to the developer,
to the implementer of the inter-rules.
It's similar to you have a reality, TypeScript, and you want to model a simplification that covers most of the cases.
What I propose is to keep the invariant that simplifies the API.
It's a reference referred to a single declaration.
And we handle edge cases with export, in fair, and others with different code.
And we keep also important characteristics at tip and variable with the same name are possible and tip and variable duality with cases, for example.
I implemented a second version of a name resolver.
In fact, the name resolver add a tag to every declaration and references, a tip or variable tag.
For example, here, the interface has a tag tip or for tip and the unique identifier we previously talked about.
And for variable, for example, function, we have a tag variable and so on.
And the reference refer ever a tip or a variable.
With this new name resolver, it's possible to detect some issues.
For example, here, we have a function, it's unused function, and the tip is used.
And one important aspect is you don't expose the tip variable duality in the semantic model.
It's only a resolving pace.
Once you resolve the names, you just remove the tag and you have previously the same API.
You can ask which declines every references of each declaration and so on.
In conclusion, Biome is a formator as a linter.
It also supports import sorting.
Biome is fast because it's white and in a rest.
It uses multicore capabilities.
Biome is editor-ready because they use an error-tolerant parser and concrete syntax tree.
And we support TypeScript, GSX, TSX.
It's better included.
And we have a tip-aware semantic model that allows to implement some interesting rules as use import tip, use export tip.
This year and later, we plan to implement, to support more languages, CSS, HTML, Markdown, and more frameworks,
Vue, Angular, Zvelt, Astro.
We have already some support for React.
We want to improve linter capabilities, multi-file analysis, because for now, we are only able to analyze file by file.
We cannot analyze an entire project.
And we want also to implement a SAP LIFI Type System to implement some rule of USLint TypeScript.
We want also to support plugins.
It's a requested feature by many users.
And expand the tool chain with other tools.
For example, transcut transformation and so on.
If you want to help us, you can try BIOM first and report Azure feedbacks.
You can also contribute to BIOM.
We have a good first Azure on the repository.
We have a great resource to create an inter-rule.
Emma, the other lead partner, created a video for creating an inter-rule.
If you have money, you can sponsor us also.
Thank you.
And I just put some comments.
In fact, you can format your code base, you can link, and you can do both with a single comment, format and link.
Thanks.
I have some questions.
Yes?
What was the question you talked about?
Sorry, I don't...
What vision of ECMAScript do you talk about?
Atmosphere.
You can maybe...
What vision of ECMAScript do you talk about?
Advertisers.
Okay. Advertisers.
ECMAScript direction.
Ah, okay. The last one.
Are there any other questions?
Can you shout?
Can we use custom rules?
Can we write custom rules already?
It's a recurrent question.
Currently, no, because we don't support plugins.
But we have a core contributor, but currently working on that.
We explore two options.
First is WSM or JavaScript possibility for writing plugins.
And another one is with domain-specific language.
Maybe with a grid QL.
Yes?
For large projects that have large stinker operations,
it might be difficult to switch to the bio-jazz stuff.
You can have some library to generate bio-contagrations
based on some existing configuration.
Yes.
In the next version, we plan to add some migration tools for pressure.
But we're also thinking about doing the same for ESLint.
Unfortunately, we have some differences with ESLint.
Most of the ESLint rules have an equivalent biome rule.
But we have some differences in the option.
For example, we support less options because sometimes we think it's not relevant to support some options.
And we have also some rules are split in two rules, for example.
I can give you an example.
It's NoVis alias in ESLint.
In fact, ESLint forbid you to write, for example, const self,
equal this.
In fact, we think it's too restrictive.
We decide to split in two rules.
First is NoVuselessVis alias.
In fact, it checks for use less Vis alias.
For example, you use an arrow function here.
You don't need to alias this with self.
You can just remove the aliasing.
And you have a second rule.
It's use the arrow function that try to replace function with arrow function.
And combining both, you have the same functionality as ESLint,
but less opinionated.
And we have also overruled more strict, but depend of the case.
And this kind of differences make a bit hard to create a migration tool,
but we're working on that.
Yes?
Sorry, the large advantage of criteria compared to formatting tools that came before it was its opinionatedness.
What is your stance on the opinionatedness for the biogest?
Sorry, can you just repeat the question each time, because for the live streaming?
The question is, the pressure is opinionated, is biome the same?
Yes, because in fact we decide to match the pressure output because of the challenge.
And we implemented every option of pressure, and we decide to match its output.
And yes, some users are not so happy because they don't like pressure.
But most of the version of ESLint uses pressure.
I think it's a good thing to match pressure on that.
Yes?
With TypeScript ESLint, it has some quite advanced rules, but it depends on the type.
So for example, it will warn you if you call an async function without using await,
because it knows that the function returns, I promise.
Is this the kind of thing you do at the moment, and if not, do you have plans for that kind of semantic analysis?
Yes.
In fact, currently we implement about all the rules of TypeScript ESLint.
It's basically all rules that don't require tip information.
And for this kind of rule, no floating promises, I think so.
It's this rule, yes.
We need tip information.
We have several ideas, but personally and the team also want to explore
a simplified TAP system.
In fact, we want to base our implementation on the new, the upcoming
isolated declaration mode of TypeScript.
It's for the next version or maybe the next one.
And the idea is you require to have a bit more annotation in the code
and combine this mode with a simplified tip inference system
you can in fact achieve most of the type query in a code base.
And I think this mode will gain a lot of support because it's built by Bloomberg
and it brings a lot of performances in the TypeScript world.
In one or two years, this mode will be the default.
I think it's a great bet for us.
Thanks.
Any other questions?
No.
Big round of applause for Zipfana.