• Stars
    star
    6,334
  • Rank 6,007 (Top 0.2 %)
  • Language
    TypeScript
  • License
    BSD 2-Clause "Sim...
  • Created about 7 years ago
  • Updated 12 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

High performance, maintainable stylesheets.

CSS Blocks

Blazing fast CSS for your Design Systems and App Components

Build Status Greenkeeper badge


CSS Blocks is an ergonomic, component-oriented CSS authoring system that compiles to high-performance stylesheets.

By combining an opinionated authoring system, build-time analysis and rewriting of templates, and a new type of CSS optimizer, css-blocks breathes new power and ease of use into the technologies and best practices that stylesheet developers already know and love.

Interested in contributing, or just seeing CSS Blocks in action? Head over to CONTRIBUTING.md to learn how to spin up the project!

Table of Contents

Why CSS Blocks?

With css-blocks added to your project, you receive:

  • 💎 One CSS File Per Component
  • 📦 Scoped Styles
  • 🔎 Nearly Non-Existent Runtime (~500b)
  • 🔥 Blazing Fast Stylesheets
  • 🚀 Project-Wide Optimization
  • 🚨 Build Time CSS Errors
  • 🧟 Dead Code Elimination
  • Object Oriented Inheritance

But, most importantly, CSS Blocks is ⚡️Statically Analyzable.

The ⚡️ of Static Analysis

Static analysis means css-blocks can look at your project and know with certainty that any given CSS declaration will, will not, or might under certain conditions, be used on any given element in your templates.

Most stylesheet architectures have to walk a fine line between performance and maintainability. Tilt too far in either direction and either your users or the developers will end up paying the cost. With CSS Blocks, you can focus on making sure your stylesheets are easy to maintain as your application changes, and with the new CSS optimizer, OptiCSS, the small size of your app's production stylesheets after compression will amaze you.

Gone are the days where you spend several minutes debugging your app only to discover a subtle typo that caused a selector to not match – CSS Blocks will give you a build error and suggest possible fixes. With IDE integration, projects using CSS Blocks will be able to quickly navigate to selector definitions that match your current template element and find which template elements match your current selector, autocomplete class names. With CSS Blocks new resolution system, cascade conflicts will be caught for you before you even know they exist and you will never have to fight a specificity war ever again.

CSS Blocks Example

CSS Blocks is inspired by CSS Modules, BEM and Atomic CSS

For a full deep-dive of the project architecture, I heavily recommend you review the CSS Blocks Architecture README!

⚙️ Supported Integrations

CSS Blocks requires deep integration with your build system and templating language. To learn how to install css-blocks for in your application, please consult the specific docs for your templating system and build system.

CSS Blocks is available for use in the following templating languages:

And has integrations with the following build systems:

Don't see your preferred platform yet?

Learn how to make your own Template Integration or Build System Integration and contribute it back!

🎁 API Features

CSS Blocks is under active development and there are a number of features that have not yet been implemented! You can get a snapshot of the feature-set state here.

= Implemented | = Not Implemented | 💀 = Deprecated | 🖌 = In Proposal |

Status Feature Description
Selectors
:scope Scope selector for component root.
.class Class selectors for component sub-elements.
.class[name] State that is applied to scope and class selectors on state existence.
.class[name="value"] Mutually exclusive sub-states for scope and class selectors to be applied when a sub-state value matches.
[name=value] Bare state (not associated with an Originating Element) and optional substate selectors for targeting all elements in the Block that possess the state and/or sub-state.
🖌 .class[name=value default] Default state value to be applied when there is no other match.
At Rules
@block local-name from "./file/path.css" Reference another Block using a local name.
@block-debug block-name to channel Debug call that will print a block interface to a "channel": comment, stderr, or stdout.
@block-global block.path Declare a Block class or state as public. It may be used as a context selector in other Blocks.
Properties
block-name: "custom-name"; Provide custom Block names in :scope for a nicer debugging experience.
implements: block-name; A Block can declare that it implements one or more other Block's interfaces in its :scope selector and the compiler will ensure that all of those states and classes are styled locally.
extends: block-name; A Block may specify it extends another Block in its :scope selector to inherit and extend all the class and state implementations therein.
composes: "block.path"; Mixin-Style class and state composition. Apply other Blocks' Styles to one of yours.
Functions
resolve("block.path"); Provide an explicit resolution for a given property against another Block.
constrain(val1, val2 ... valN); Constrain this property to a list of specific values that may be set when this Block is extended.
range(min, max); Constrain this property to a range of values that may be set when this Block is extended.

🎨 What is a Block?

A "Block" is an isolated stylesheet, written in its own file, that contains all rulesets for any elements, and their various modes and interaction states, for a discrete unit of styling – like a component or design pattern.

Typically, a single Block will contain styles for a particular component or concept, but it is entirely natural – and encouraged – for a template to consume multiple blocks and compose them together in the markup.

A Block file may contain:

The Scope Selector

The scope ruleset contains styles applied to the root of the scoped style subtree. All other elements assigned styles from a Block must be contained in the document subtree of an element assigned to the block's :scope. We use the special :scope pseudo-class to represent these styles.

The :scope selector may contain the special block-name property so you may provide your own Block name for easy debugging and BEM class generation. If no block-name is provided, we will infer the Block name from the file name.

💡 Feature Note: Block Names

If two Blocks in your project have the same name, CSS Blocks will automatically generate a unique, but still human-readable, name for BEM output mode.

:scope {
  block-name: custom-block-name;
  /* 👆 optional! */
  /* ... more styles ... */
}

Class Selectors

Blocks may can contain other classes that may be applied to elements inside the scoped style sub-tree. These are just class selectors, but they are local to that Block and isolated from all other similarly named classes in other Blocks.

.sub-element { /* ... */ }
.other-sub-element { /* ... */ }

Together, the :scope selector and all declared .class selectors define the full interface of stylable elements available to a Block's consumer.

State Selectors

States represent a mode or interaction state that the :scope or a class – called the state's originating element – may be in. States are written as attribute selectors with the special state namespace.

:scope { /* ... */ }
:scope[enabled] { /* ... */ }

.sub-element { /* ... */ }
.sub-element[is-active] { /* ... */ }

⁉️ What the pipe is going on here?

Once upon a time, developers fell in love with XML and thus was born xhtml, a flavor of HTML that allowed HTML elements to be mixed together with elements from other XML syntaxes like SVG and MathML. CSS went along for the ride and so, while many have never seen or used the feature, CSS has support for namespaced elements and attributes. In CSS, the | symbol is used to delimit between a namespace identifier (assigned by the @namespace at-rule) and the element or attribute name (also called a qualified name).

In markup, instead of a pipe symbol, the colon is used to delimit a namespace identifier and a qualified name. Yes, this is confusing -- but we don't make CSS syntax, we just use it.

Sub-State Selectors

States on the :scope selector or a class selector may contain sub-states for more granular styling. Sub-states of a State are mutually exclusive and an element may only be in one sub-state of that state at any given time.

:scope { /* ... */ }
:scope[theme="inverse"] { /* ... */ }

.sub-element { /* ... */ }

/* Applied for *any* value of `color`, including no value. */
.sub-element[color] { /* ... */ }

/* Applied for *specific* values of `color */
.sub-element[color="red"] { /* ... */ }
.sub-element[color="blue"] { /* ... */ }
.sub-element[color="yellow"] { /* ... */ }

Its Just CSS!™️ (mostly)

CSS Blocks implements a strict subset of CSS. This means we've intentionally restricted some of the features you're allowed to use in a Block file to ensure we can optimize your stylesheets as much as possible!

As Opticss improves, we may choose to loosen some of these restrictions – keep an eye out for syntax updates as we approach the v1.0.0 release!

🎉 That means you may freely use:

🚨 However:

  • !important is forbidden – you won't be needing it!
  • The tag, non-state [attribute], #id and * selectors are forbidden (for now!)
  • The Logical Combinators :matches(), :not(), :something() and :has() are forbidden (for now!)
  • Selectors must remain shallow.

In css-blocks, shallow selectors mean:

1) Only one combinator per selector.

/* ✅ Allowed! */
:scope:hover > .my-class { /* ... */ }

/* ❌ Illegal! */
:scope:hover > .my-class + .my-class { /* ... */ }

2) The Hierarchical Combinators' (" " and ">") context selector must be a :scope states, sub-states, or pseudo-classes.

/* ✅ Allowed! */
:scope:hover .my-class { /* ... */ }
:scope[active] > .my-class { /* ... */ }
:scope[color=red] .my-class { /* ... */ }

/* ❌ Illegal! */
.container:hover > .my-class { /* ... */ }
.container[active] .my-class { /* ... */ }
.container[color=red] .my-class { /* ... */ }

3) The Sibling Combinators' ("+", "~") context selector must target the same class or :scope used in the key selector.

/* ✅ Allowed! */
.my-class + .my-class { /* ... */ }
.my-class:hover ~ .my-class { /* ... */ }
.my-class[active] + .my-class { /* ... */ }

/* ❌ Illegal! */
:scope + .my-class { /* ... */ }
.another-class:hover ~ .my-class { /* ... */ }
.another-class[active] + .my-class { /* ... */ }

💡 Feature Note: Global States and Selectors

"Global States" have their own rules on how they can be used in Block selectors! Keep an eye out for them a little later in this doc.

Of course, because we statically analyze and compile all your code before it ever hits the browser, you will get a helpful error if any of these syntax restrictions are violated.

Blocks in Your Templates

Every specific template integration with css-blocks will have their own slightly unique syntax for how to interface with Block files. However, they all will allow you to apply classes and states in a way that is analyzable and rewritable at build time.

💡 Feature Note: Template Integrations

Each integration implements a slightly different API. Ex: JSX lets you import Block files, Ember looks for, through convention, a stylesheet.css alongside every component template. Check out the README for your template language for full details.

However, whatever the implementation is, it will feel as though you're interfacing with regular CSS on the platform. For example, in Glimmer you just write the classes and states exactly as you would expect when working with a normal stylesheet:

:scope { /* ... */ }
:scope[enabled] { /* ... */ }
.button { /* ... */ }
.icon { /* ... */ }
.icon[inverse] { /* ... */ }
{{!-- :scope selector is automagically applied to the template's root-level element. Thanks Glimmer! --}}
<section block:enabled={{isEnabled}}>
  <button block:class="button">
    <div block:class="icon" block:inverse={{isInverse}}></div>
    {{value}}
  </button>
</section>

There are only two (2) common-sense rules to follow when using Block styles in your template:

  1. You may not use a Block class outside of it's :scope's subtree.
  2. Two classes from the same Block may not be applied to the same HTML element.

🏗 Block Composition

Blocks styles are, by design, scoped to the file they are written in, but we all know that in a real app your styles can't live in a vacuum!

As you'll see below, there are many methods to compose blocks together in your application. However, most of these methods will begin with the humble @block.

Block References

A Block may declare a dependency on another Block by using a @block at the top of your file. A @block creates a locally scoped alias where you can access the public API (declared classes and states) of the referenced block.

Block references don't cause any styles to be included. Instead, they are like an ES6 import statement -- they make it possible to refer to the public interface of another Block from within the current Block.

Adding a @block is as simple as this:

/* block-1.block.css */
:scope { block-name: block-1; }
.my-class { /* ... */ }
.my-class[my-state] { /* ... */ }
/* block-2.block.css */
@block other-block from "./block-1.block.css";

:scope { block-name: block-2; }

🔮 Future Feature: Node Modules Block Resolution

Whether you're integrating with a 3rd party library, or pulling in dependencies internal to your company, at some point you'll want to integrate with styles delivered via NPM! The resolution logic for @blocks to node_modules hasn't yet been implemented yet, but you can track progress (or even help out!) over on Github.

With the above code, block-2 now has a local reference other-block which points to block-1. We can now freely use the other-block identifier inside of block-2 when we want to reference reference block-1. This comes in handy! Especially with features like:

Object Oriented Features of Blocks

Block Implementation

A Block's public interface is defined by the states and classes it styles. A block may declare that it implements one or more other referenced blocks' interfaces, and the compiler will ensure that all the states and classes it defines are also in the implementing block. In this way, the compiler can guarantee it is safe to use different blocks to style the same markup in a component.

You do this via the special implements property in a Block's :scope selector:

/* block-1.block.css */
:scope { block-name: block-1; }
.my-class { /* ... */ }
.my-class[my-state] { /* ... */ }
/* block-2.block.css */
@block other-block from "./block-1.block.css";

:scope {
  block-name: block-2;
  implements: other-block;
}

💡 Feature Note: Implements Property

The implements property is only available in the :scope selector. If you use it in any other selector, it will be ignored.

However, the above code will throw an error at build time!

$ Error: Missing implementations for .my-class, .my-class[my-state] from ./block-1.block.css

For the build to pass, we need to implement the full public interface of block-1 in block-2:

/* block-2.block.css */
@block other-block from "./block-1.block.css";

:scope {
  block-name: block-2;
  implements: other-block;
}
.my-class { /* ... */ }
.my-class[my-state] { /* ... */ }

Block Inheritance

A Block may also choose to extend another referenced Block. This exposes all declared styles from the extended Block on the extending Block.

Those inherited styles may then be used in a template by accessing them on the extending block, and can even be augmented by re-declaring the styles in the extending block!

You do this via the special extends property in a Block's :scope selector.

Lets say we have a component called <basic-form>. Basic forms have an input element, and a big green button. Simple enough:

/* basic-form.block.css */
.button {
  font-size: 1.4rem;
  color: white;
  background-color: green;
}
.button[disabled] {
  color: #333;
  background-color: lightgray;
}
.input { font-weight: bold }

But, as the project evolves we realize we need a new form for submitting information for a dangerous action, we're asked to create a new kind of form called <danger-form>. Danger forms look and function exactly the same as a basic form, except the button and labels are red. We could re-implement the entire stylesheet to create <danger-form>, but that would be a such a waste of all the hard work we already put in to <basic-form>!

Instead, we can simply extend the <basic-form> Block, and only apply the small style changes we need:

/* danger-form.block.css */
@block basic-form from "./basic-form.block.css";

:scope  { extends: basic-form; }
.button { background-color: darkred; }
.label  { color: darkred; }

During rewrite, references to an inherited style will translate into the class(es) for the directly referenced style as well as all the classes that it inherits from so developers do not need to bring the complexity of the inheritance relationship into their templates. For example, a reference to danger-form.button would result in adding both .basic-form__button, as well as .danger-form__button to the element's list of classes.

When the blocks are compiled, property overrides are detected and automatically resolved. The selectors generated serve two purposes:

  1. Concatenation order independence - Once compiled, a CSS block file can be concatenated in any order with other compiled block output.
  2. Optimization hints - Normally, if there are selectors with the same specificity that set same property to different values on the same element, the optimizer would take care not to merge those declarations such that it might cause a cascade resolution change. But the selectors in the output from CSS Blocks allows OptiCSS to merge declarations more aggressively, because it can prove that it knows the value of those selectors when combined.
.basic-form__button { font-size: 1.4rem; color: white; background-color: green; }
.basic-form__button--disabled { color: #333; background-color: lightgray; }
.basic-form__input { font-weight: bold; }
.danger-form__button { background-color: darkred; }
.basic-form__button.danger-form__button { background-color: darkred; }
.danger-form__button--disabled { background-color: #957d7d; }
.basic-form__button.danger-form__button--disabled { background-color: #957d7d; }
.basic-form__button--disabled.danger-form__button--disabled { background-color: #957d7d; }
.danger-form__label { color: darkred; }

While this output is highly repetitive and may seem excessive, it's exactly the kind of repetition that OptiCSS is designed to search for and remove. From an authoring experience and in production, it's a laser-focused override with no performance impact.

💡 Feature Note: Extends Property

The extends property is only available in the :scope selector. If you use it in any other selector, it will be ignored.

An extending block is able to re-define any property on any style it inherits from. CSS declarations defined in the extending Block will always take priority over the definitions inherited by the same named Style in the base Block.

🔮 Future Feature: Extension Constraints

Sometimes, properties inside of a component are so important, that authors may want to constrain the values that extenders and implementors are able to set. In the near future, css-blocks will enable this use case through the custom constrain() and range() CSS functions and possibly through other ideas like custom constraints and conflicts. You can come help out over on Github to make this happen faster!

Style Composition

Block Paths

As your Blocks begin interacting with each other in increasingly complex ways, you will find yourself needing to reference specific classes or states on another Block, as you'll see later in this document. You do this using a small query syntax called a Block Path.

Block Paths take the form:

block.class[name='value']

All sections of this selector – except the leading Block name – are optional. The leading Block name must refer to an imported @block at the top of the file. If css-blocks is unable to resolve a Block Path at build time, you will get a friendly error message in your console!

All the following syntaxes are legal to select any given stylable on a referenced Block:

Stylable Syntax
Scope block
Scope State block[name]
Scope Sub-State block[name=value]
Class block.class
Class State block.class[name]
Class Sub-State block.class[name=value]

🔮 Future Feature: Block Path Wildcards

In some situations, you may want to select multiple classes, states or sub-states on a referenced block. In the near future you will be able to do so with a wildcard syntax: block.*, block.class[*], block.class[name=*]. Feel free to track progress of this feature here

Composition in Templates

Every template integration will provide a way to use more than one Block inside of a template. The syntax for this may change depending on your templating system, so please check with your specific template integration's documentation.

For Glimmer, using multiple blocks in a single template will look something like this:

/* hoverable.css */
:scope {
  block-name: hoverable;
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.2);
  transition: box-shadow .28s;
}
:scope:hover {
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2)
}
.button {
  background-color: rgba(255, 255, 255, .5);
  color: black;
  transition: background-color .28s;
}
:scope:hover .button {
  background-color: rgba(255, 255, 255, 1);
}
/* stylesheet.css */
@block other from "./hoverable.css";

:scope { block-name: main; }
.form {
  border: 1px solid gray;
  border-radius: 2px;
  padding: 16px;
}
.button {
  background-color: green;
  color: white;
  height: 32px;
  width: 100%;
}
{{!-- :scope selector from `stylesheet.css` is automagically applied to the template's wrapper element. Thanks Glimmer! --}}
<section>
  <form class="form other">
    <button class="button other.button">Click Me!</button>
  </form>
</section>

Above we have a simple template that contains a form with a single button that says "Click Me!". We style it with styles from the default Block for the template, stylesheet.css, and with styles from the referenced Block hoverable.css, referenced in this context as other.

In this template, we have the <form> element assigned the scoped root for other, and we apply the button class from both blocks to the <button> element.

But wait! If you try and run the css-blocks build with this code, you'd find an error in your console!

The following property conflicts must be resolved for these co-located Styles: (template.hbs:4:19)

          color:
            main.button (stylesheet.css:12:2)
            hoverable.button (hoverable.css:12:2)

          background-color:
            main.button (stylesheet.css:11:2)
            hoverable.button (hoverable.css:11:2)

Woah, what does this mean?! Well, if we stop and think for a second about what we just asked css-blocks to do, we'll realize that this error makes perfect sense.

Because Blocks have their own entirely independently scoped cascades, and right now no Block file is aware of any other Block's styles, css-blocks doesn't inherently know which Block should take priority over another when used together.

So, when css-blocks was asked to put the .button class from both the default template stylesheet, and from hoverable onto the same element, it noticed that both classes are claiming to set the color and background-color properties – and with this we have encountered our first Indeterminate Cascade Resolution.

Which Block should win in this situation? Right now, the compiler has no idea. To answer that, css-blocks needs a little help from you. We are able to provide explicit cross-Block cascade resolutions to the compiler by using resolve(). Lets learn how we can fix our above error by moving on to the next section: Block Resolutions.

Block Resolutions

The special resolve() function provides explicit resolution guidance for properties that are in conflict across two or more Block files. They look like any other property declaration:

selector {
  property-name: resolve("<block-path>");
}

You will be asked by the css-blocks compiler to add resolutions if and when two styles are found on the same element in your templates that attempt to set the same CSS property.

Resolve declarations work just like progressive enhancement and graceful degradation! The last declaration defined in the ruleset will win. This means that declaration order matters. There are two ways to resolve any given property:

Override Resolution

Override resolutions tell css-blocks that when these two styles are used together, we want this Block to override the value of the other Style's property.

Here, we tell css-blocks to use the color value from my-class instead of other.selector when both styles are applied to the same element:

.my-class {
  color: resolve("other.selector");
  color: red;
}

Yield Resolution

Yield resolutions tell css-blocks that when these two styles are used together, we want this Block to yield to the value of the other Style's property.

Here, we tell css-blocks to use the color value from other.selector instead of my-selector when both styles are applied to the same element:

.my-class {
  color: red;
  color: resolve("other.selector");
}

🔮 Future Feature: Resolve All Shorthand

For straightforward resolutions where you just want to yield or assume full control of styling against another block, feel free to use the CSS all property to quickly override or yield to all property conflict with another block. The downside of doing this is that as new properties are added to another element, you don't get a chance to review them and decide:

.my-class {
  color: red;
  background: blue;

  /* Yields all conflicts to `other.selector` */
  all: resolve("other.selector");
}

💡 Feature Note: Advanced Property Conflicts

The css-blocks compiler is smart! If you have dynamic classes or states in your template, it will ask you to provide explicit resolutions between Blocks that even only have a chance of being used together on the same element. This way, we can guarantee that your styles will work regardless of the state your application may find itself it.

Css Blocks is also aware of CSS shorthands and will ask you to resolve the lowest common denominator on conflicting shorthand/longhand expressions as well.

So, continuing with the example from the previous section – Composition in Templates – we can satisfy the css-blocks compiler by adding in two explicit resolutions for color and background-color like so:

/* stylesheet.css */
/* ... */

.button {
  /* Override Resolution */
  background-color: resolve("hoverable.button");
  background-color: green;

  /* Override Resolution */
  color: resolve("hoverable.button");
  color: white;

  /* ... */
}

Here we have told css-blocks that when our component's .button class is used with hoverable's .button class, we want our component's style declarations to win! We have declared an override resolution for both properties.

If we were to switch around the order a bit so our background-color resolution comes after our component's declaration, it means that when these two classes are used together, hoverable's .button class will win, but only for that property. This is why you will never have to fight the cascade or use !important ever again!

/* stylesheet.css */
/* ... */

.button {
  /* Yield Resolution */
  background-color: green;
  background-color: resolve("hoverable.button");

  /* Override Resolution */
  color: resolve("hoverable.button");
  color: white;

  /* ... */
}

💡 Feature Note: States and Pseudo-Classes

States and Pseudo-Classes inherit all resolutions set on their containing Class or :scope.

This means that in the above example, where we yield for background-color, and override for color, the button element where both classes are used will still use hoverable.button:hover's background-color, but it's color will remain white, like our component styles define!

Resolving Pseudo Elements

It is important to note that Pseudo-Elements do not inherit any resolutions from their container class and must be explicitly resolved in the source stylesheets when found to be in conflict.

So, for the following two Blocks where my-class-1[enabled] and my-class-2 are used on the same element, one of the Blocks will need to resolve the conflicting border-width property:

/* other */

.my-class-1[enabled]::before {
  border: 1px solid red;
}
/* main.css */

@block other from "./other.css";

.my-class-2::before {
  border-width: 2px;
  border-width: resolve("other.my-class-2[enabled]");
}

External Selectors

Sometime a class, identifier, or tag name comes from an external source, and the only thing you can do is use them as is. In these situations the Block must declare all external simple selectors it intendeds to use. These simple selectors may then be used as key selectors inside this Block. You'll get an error for any declared external selectors that aren't used or if they are used in the context selector.

Styles targeting an external selector are not rewritten and their declarations cannot be optimized! Style collisions on an external selector are not detected or resolved. As a result, it is allowed to use !important on declarations targeting an external selector.

Warning: If external selectors and CSS block objects both target the same HTML element in their key selectors you will get unpredictable results. It's best to avoid this.

@external h2.some-rando-class;

.foo h2.some-rando-class {
  font-size: 32px !important;
}

Global States

In rare occasions, a Block may choose to declare declare that a certain State is global. These states are special in that they can be used in other Blocks like they are local to that block.

This is most useful for global application states – like during initial application boot, or when a modal is displayed.

⚙️ Performance Note: Global States

When you apply classes and other attributes to elements like <html> or <body> it invalidates a lot of internal caches in the browser. It is still often a performance win compared to querying the document in javascript and applying classes on many elements.

/* application.block.css */

@block-global [is-loading];
@block-global [is-saving];
/* navigation.block.css */

@block app from "application.block.css";

/* Gray out signout button when app is saving */
:scope[app|is-saving] .signout {
  color: gray;
  pointer-events: none;
}

/* Animate the logo when app is loading data */
:scope[app|is-loading] .logo {
  animation-name: bounce;
}

More Repositories

1

school-of-sre

At LinkedIn, we are using this curriculum for onboarding our entry-level talents into the SRE role.
HTML
7,649
star
2

Burrow

Kafka Consumer Lag Checking
Go
3,644
star
3

databus

Source-agnostic distributed change data capture system
Java
3,587
star
4

qark

Tool to look for several security related Android application vulnerabilities
Python
3,117
star
5

dustjs

Asynchronous Javascript templating for the browser and server
JavaScript
2,917
star
6

cruise-control

Cruise-control is the first of its kind to fully automate the dynamic workload rebalance and self-healing of a Kafka cluster. It provides great value to Kafka users by simplifying the operation of Kafka clusters.
Java
2,634
star
7

rest.li

Rest.li is a REST+JSON framework for building robust, scalable service architectures using dynamic discovery and simple asynchronous APIs.
Java
2,435
star
8

kafka-monitor

Xinfra Monitor monitors the availability of Kafka clusters by producing synthetic workloads using end-to-end pipelines to obtain derived vital statistics - E2E latency, service produce/consume availability, offsets commit availability & latency, message loss rate and more.
Java
1,991
star
9

dexmaker

A utility for doing compile or runtime code generation targeting Android's Dalvik VM
Java
1,843
star
10

greykite

A flexible, intuitive and fast forecasting library
Python
1,788
star
11

ambry

Distributed object store
Java
1,717
star
12

shiv

shiv is a command line utility for building fully self contained Python zipapps as outlined in PEP 441, but with all their dependencies included.
Python
1,693
star
13

swift-style-guide

LinkedIn's Official Swift Style Guide
1,436
star
14

dr-elephant

Dr. Elephant is a job and flow-level performance monitoring and tuning tool for Apache Hadoop and Apache Spark
Java
1,341
star
15

detext

DeText: A Deep Neural Text Understanding Framework for Ranking and Classification Tasks
Python
1,254
star
16

parseq

Asynchronous Java made easier
Java
1,158
star
17

luminol

Anomaly Detection and Correlation library
Python
1,151
star
18

oncall

Oncall is a calendar tool designed for scheduling and managing on-call shifts. It can be used as source of dynamic ownership info for paging systems like http://iris.claims.
Python
1,095
star
19

test-butler

Reliable Android Testing, at your service
Java
1,040
star
20

goavro

Go
948
star
21

PalDB

An embeddable write-once key-value store written in Java
Java
934
star
22

brooklin

An extensible distributed system for reliable nearline data streaming at scale
Java
891
star
23

iris

Iris is a highly configurable and flexible service for paging and messaging.
Python
791
star
24

photon-ml

A scalable machine learning library on Apache Spark
Terra
790
star
25

Hakawai

A powerful, extensible UITextView.
Objective-C
780
star
26

URL-Detector

A Java library to detect and normalize URLs in text
Java
778
star
27

eyeglass

NPM Modules for Sass
TypeScript
741
star
28

opticss

A CSS Optimizer
TypeScript
715
star
29

coral

Coral is a translation, analysis, and query rewrite engine for SQL and other relational languages.
Java
714
star
30

LiTr

Lightweight hardware accelerated video/audio transcoder for Android.
Java
590
star
31

pygradle

Using Gradle to build Python projects
Java
584
star
32

kafka-tools

A collection of tools for working with Apache Kafka.
Python
581
star
33

flashback

mock the internet
Java
578
star
34

LayoutTest-iOS

Write unit tests which test the layout of a view in multiple configurations
Objective-C
565
star
35

FeatureFu

Library and tools for advanced feature engineering
Java
564
star
36

FastTreeSHAP

Fast SHAP value computation for interpreting tree-based models
Python
493
star
37

venice

Venice, Derived Data Platform for Planet-Scale Workloads.
Java
413
star
38

Spyglass

A library for mentions on Android
Java
381
star
39

dagli

Framework for defining machine learning models, including feature generation and transformations, as directed acyclic graphs (DAGs).
Java
353
star
40

ml-ease

ADMM based large scale logistic regression
Java
333
star
41

cruise-control-ui

Cruise Control Frontend (CCFE): Single Page Web Application to Manage Large Scale of Kafka Clusters
Vue
329
star
42

transport

A framework for writing performant user-defined functions (UDFs) that are portable across a variety of engines including Apache Spark, Apache Hive, and Presto.
Java
288
star
43

dph-framework

HTML
285
star
44

spark-tfrecord

Read and write Tensorflow TFRecord data from Apache Spark.
Scala
276
star
45

openhouse

Open Control Plane for Tables in Data Lakehouse
Java
256
star
46

isolation-forest

A Spark/Scala implementation of the isolation forest unsupervised outlier detection algorithm.
Scala
217
star
47

LiFT

The LinkedIn Fairness Toolkit (LiFT) is a Scala/Spark library that enables the measurement of fairness in large scale machine learning workflows.
Scala
167
star
48

shaky-android

Shake to send feedback for Android.
Java
157
star
49

pyexchange

Python wrapper for Microsoft Exchange
Python
151
star
50

asciietch

A graphing library with the goal of making it simple to graphs using ascii characters.
Python
137
star
51

python-avro-json-serializer

Serializes data into a JSON format using AVRO schema.
Python
136
star
52

li-apache-kafka-clients

li-apache-kafka-clients is a wrapper library for the Apache Kafka vanilla clients. It provides additional features such as large message support and auditing to the Java producer and consumer in the open source Apache Kafka.
Java
132
star
53

gdmix

A deep ranking personalization framework
Python
131
star
54

dynamometer

A tool for scale and performance testing of HDFS with a specific focus on the NameNode.
Java
129
star
55

Avro2TF

Avro2TF is designed to fill the gap of making users' training data ready to be consumed by deep learning training frameworks.
Scala
125
star
56

linkedin-gradle-plugin-for-apache-hadoop

Groovy
117
star
57

datahub-gma

General Metadata Architecture
Java
112
star
58

dex-test-parser

Find all test methods in an Android instrumentation APK
Kotlin
104
star
59

cassette

An efficient, file-based FIFO Queue for iOS and macOS.
Objective-C
95
star
60

spaniel

LinkedIn's JavaScript viewport tracking library and IntersectionObserver polyfill
JavaScript
91
star
61

Hoptimator

Multi-hop declarative data pipelines
Java
77
star
62

migz

Multithreaded, gzip-compatible compression and decompression, available as a platform-independent Java library and command-line utilities.
Java
76
star
63

sysops-api

sysops-api is a framework designed to provide visability from tens of thousands of machines in seconds.
Python
75
star
64

avro-util

Collection of utilities to allow writing java code that operates across a wide range of avro versions.
Java
73
star
65

iceberg

A temporary home for LinkedIn's changes to Apache Iceberg (incubating)
Java
60
star
66

kube2hadoop

Secure HDFS Access from Kubernetes
Java
59
star
67

linkedin.github.com

Listing of all our public GitHub projects.
JavaScript
59
star
68

dynoyarn

DynoYARN is a framework to run simulated YARN clusters and workloads for YARN scale testing.
Java
58
star
69

Tachyon

An Android library that provides a customizable calendar day view UI widget.
Java
57
star
70

DuaLip

DuaLip: Dual Decomposition based Linear Program Solver
Scala
56
star
71

iris-relay

Stateless reverse proxy for thirdparty service integration with Iris API.
Python
49
star
72

Cytodynamics

Classloader isolation library.
Java
48
star
73

concurrentli

Classes for multithreading that expand on java.util.concurrent, adding convenience, efficiency and new tools to multithreaded Java programs
Java
43
star
74

iris-mobile

A mobile interface for linkedin/iris, built for iOS and Android on the Ionic platform
TypeScript
41
star
75

instantsearch-tutorial

Sample code for building an end-to-end instant search solution
JavaScript
39
star
76

lambda-learner

Lambda Learner is a library for iterative incremental training of a class of supervised machine learning models.
Python
37
star
77

self-focused

Helps make a single page application more friendly to screen readers.
JavaScript
35
star
78

tracked-queue

An autotracked implementation of a ring-buffer-backed double-ended queue
TypeScript
35
star
79

PASS-GNN

Python
35
star
80

QueryAnalyzerAgent

Analyze MySQL queries with negligible overhead
Go
35
star
81

TE2Rules

Python library to explain Tree Ensemble models (TE) like XGBoost, using a rule list.
Python
31
star
82

performance-quality-models

Personalizing Performance model repository
Jupyter Notebook
31
star
83

Iris-message-processor

Iris-message-processor is a fully distributed Go application meant to replace the sender functionality of Iris and provide reliable, scalable, and extensible incident and out of band message processing and sending.
Go
26
star
84

smart-arg

Smart Arguments Suite (smart-arg) is a slim and handy python lib that helps one work safely and conveniently with command line arguments.
Python
23
star
85

data-integration-library

The Data Integration Library project provides a library of generic components based on a multi-stage architecture for data ingress and egress.
Java
22
star
86

linkedin-calcite

LinkedIn's version of Apache Calcite
Java
22
star
87

atscppapi

This library provides wrappers around the existing Apache Traffic Server API which will vastly simplify the process of writing Apache Traffic Server plugins.
C++
20
star
88

high-school-trainee

LinkedIn Women in Tech High School Trainee Program
Python
18
star
89

play-parseq

Play-ParSeq is a Play module which seamlessly integrates ParSeq with Play Framework
Scala
17
star
90

forthic

Python
17
star
91

icon-magic

Automated icon build system for iOS, Android and Web
TypeScript
17
star
92

QuantEase

QuantEase, a layer-wise quantization framework, frames the problem as discrete-structured non-convex optimization. Our work leverages Coordinate Descent techniques, offering high-quality solutions without the need for matrix inversion or decomposition.
Python
15
star
93

kafka-remote-storage-azure

Java
13
star
94

play-restli

A library that simplifies building restli services on top of the play server.
Java
12
star
95

spark-inequality-impact

Scala
11
star
96

AlerTiger

Jupyter Notebook
9
star
97

Li-Airflow-Backfill-Plugin

Li-Airflow-Backfill-Plugin is a plugin to work with Apache Airflow to provide data backfill feature, ie. to rerun pipelines for a certain date range.
Python
8
star
98

gobblin-elr

This is a read-only mirror of apache/gobblin
Java
5
star
99

o19-bmc-firmware

OpenBMC is an open software framework to build a complete Linux image for a Board Management Controller (BMC)
C
4
star
100

linkedin-gtm-community-template

Smarty
4
star