• Stars
    star
    200
  • Rank 195,325 (Top 4 %)
  • Language
    Swift
  • License
    Apache License 2.0
  • Created over 5 years ago
  • Updated about 2 months ago

Reviews

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

Repository Details

Declarative list views for iOS apps.

Note โ€“ Listable is still experimental ๐Ÿ™ˆ. While it is shipping in Square Point of Sale in several places, we're still actively iterating on the API, and backfilling comprehensive tests. As such, expect things to break and change in the coming months.

Listable

Listable is a declarative list framework for iOS, which allows you to concisely create rich, live updating list based layouts which are highly customizable across many axes: padding, spacing, number of columns, alignment, etc. It's designed to be performant: Handling lists of 10k+ items without issue on most devices.

self.listView.setContent { list in
    list += Section("section-1") { section in
        
        section.header = DemoHeader(title: "This Is A Header")
        
        section += DemoItem(text: "And here is a row")
        section += DemoItem(text: "And here is another row.")
        
        let rows = [
            "You can also map rows",
            "Like this"
        ]
        
        section += rows.map {
            DemoItem(text: $0)
        }
    }

    list += Section("section-2") { section in
        
        section.header = DemoHeader(title: "Another Header")
        
        section += DemoItem(text: "The last row.")
    }    
}

Features

Declarative Interface & Intelligent Updates

The core power and benefit of Listable comes from its declarative-style API, which allows you to implement SwiftUI or React style one-way data flow within your app's list views, eliminating many common state management bugs you encounter with standard UITableView or UICollectionView delegate-based solutions. You only need to tell the list what should be in it right now โ€“ it does the hard parts of diffing the changes to perform rich animated updates when new content is provided.

Let's say you start with an empty table, like so:

self.listView.setContent { list in
    // No content right now.
}

And then push in new content, so there is one row with one section:

self.listView.setContent { list in
    list += Section("section-1") { section in
        section.header = DemoHeader(title: "This Is A Header")
        
        section += DemoItem(text: "And here is a row")
    } 
}

This new section will be animated into place. If you then insert another row:

self.listView.setContent { list in
    list += Section("section-1") { section in
        section.header = DemoHeader(title: "This Is A Header")
        
        section += DemoItem(text: "And here is a row")
        section += DemoItem(text: "Another row!")
    } 
}

It will also be animated into place by the list. The same goes for any change you make to the table โ€“ a diff will be performed, and the changes will be animated into place. Content that did not change between updates will be unaffected.

Performant

A core design principle of Listable is performance! Lists are usually small, but not always! For example, within Square Point of Sale, a seller may have an item catalog of 1,000, 10,000, or even more items. When designing Listable, it was important to ensure that it could support lists of these scales with minimum performance cost, to make it easy to build them without paying for performance, or without having to drop back down to standard UITableView or UICollectionView APIs, which are easy to misuse.

This performance is achieved through an internal batching system, which only queries and diffs the items needed to display the current scroll point, plus some scrollover. Views are only created for what is currently on screen. This allows culling of most content pushed into the list for long lists.

Further, height and sizing measurements are cached more efficiently than in a regular collection view implementation, which for large lists, can boost scrolling performance and prevent dropped frames.

Highly Customizable

Listable makes very few assumptions of the appearance of your content. The currency you deal with is plain UIViews (not UICollectionViewCells), so you can draw content however you wish.

Further, the layout and appearance controls vended by ListView allow for customization of the layout to draw lists in nearly any way desired.

This is primarily controlled through the Appearance object:

public struct Appearance : Equatable
{
    public var backgroundColor : UIColor
    
    public var direction : LayoutDirection
    
    public var stickySectionHeaders : Bool
    
    public var list : TableAppearance
}

You use the TableAppearance.Sizing struct to control the default measurements within the list: How tall are standard rows, headers, footers, etc.

public struct TableAppearance.Sizing : Equatable
{
    public var itemHeight : CGFloat
    
    public var sectionHeaderHeight : CGFloat
    public var sectionFooterHeight : CGFloat
    
    public var listHeaderHeight : CGFloat
    public var listFooterHeight : CGFloat
    
    public var itemPositionGroupingHeight : CGFloat
}

You can use TableAppearance.Layout to customize the padding of the entire list, how wide the list should be (eg, up to 700px, more than 400px, etc) plus control spacing between items, headers, and footers.

public struct TableAppearance.Layout : Equatable
{
    public var padding : UIEdgeInsets
    public var width : WidthConstraint

    public var interSectionSpacingWithNoFooter : CGFloat
    public var interSectionSpacingWithFooter : CGFloat
    
    public var sectionHeaderBottomSpacing : CGFloat
    public var itemSpacing : CGFloat
    public var itemToSectionFooterSpacing : CGFloat
    
    public var stickySectionHeaders : Bool
}

Finally, the Behavior and Behavior.Underflow allows customizing what happens when a list's content is shorter than its container view: Should the scroll view bounce, should the content be centered, etc.

public struct Behavior : Equatable
{
    public var keyboardDismissMode : UIScrollView.KeyboardDismissMode
    
    public var underflow : Underflow
struct Underflow : Equatable
{
    public var alwaysBounce : Bool
    public var alignment : Alignment
    
    public enum Alignment : Equatable
    {
        case top
        case center
        case bottom
    }
}

Self-Sizing Cells

Another common pain-point for standard UITableViews or UICollectionViews is handling dynamic and self sizing cells. Listable handles this transparently for you, and provides many ways to size content. Each Item has a sizing property, which can be set to any of the following values. .default pulls the default sizing of the item from the List.Measurement mentioned above, where as the thatFits and autolayout values size the item based on sizeThatFits and systemLayoutSizeFitting, respectively.

public enum Sizing : Equatable
{
    case `default`
    
    case fixed(CGFloat)
    
    case thatFits(Constraint = .noConstraint)
    
    case autolayout(Constraint = .noConstraint)
}

Integrates With Blueprint

Listable integrates closely with Blueprint, Square's framework for declarative UI construction and management (if you've used SwiftUI, Blueprint is similar). Listable provides wrapper types and default types to make using Listable lists within Blueprint elements simple, and to make it easy to build Listable items out of Blueprint elements.

All you need to do is take a dependency on the BlueprintUILists pod, and then import BlueprintUILists to begin using Blueprint integration.

In this example, we see how to declare a List within a Blueprint element hierarchy.

var elementRepresentation : Element {
    List { list in
        list += Section("podcasts") { section in
            
            section += self.podcasts.map {
                PodcastRow(podcast: $0)
            }
        }
    }
}

And in this example, we see how to create a simple BlueprintItemContent that uses Blueprint to render its content.

struct DemoItem : BlueprintItemContent, Equatable
{
    var text : String
    
    // ItemContent
    
    var identifierValue: String {
        return self.text
    }
    
    // BlueprintItemContent
    
    func element(with info : ApplyItemContentInfo) -> Element
    {
        var box = Box(
            backgroundColor: .white,
            cornerStyle: .rounded(radius: 6.0),
            wrapping: Inset(
                uniformInset: 10.0,
                wrapping: Label(text: self.text)
            )
        )
        
        box.borderStyle = .solid(color: .white(0.9), width: 2.0)
        
        return box
    }
}

Instruments.app Integration

Listable provides integration with the os_signpost API for measuring the duration of events in your application. If you are experiencing issues with list performance in your app, you can profile it in Instruments, and add the os_signpost instrument to inspect the timing for various layout and update passes.

Primary API & Surface Area

Most of your interaction will be three primary families of types: ListView, Item, HeaderFooter, and Section.

ListView

The list that you put content into! Beyond allocating a list and putting it on screen, the bulk of your interaction with ListView will be through the setContent API shown above.

self.listView.setContent { list in
    // Set list appearance, specify content, etc...
}

What is that list parameter, you ask...?

ListProperties

ListProperties is a struct which contains all the information required to render a list update.

public struct ListProperties
{
    public var animatesChanges : Bool

    public var layoutType : ListLayoutType
    public var appearance : Appearance
    
    public var behavior : Behavior
    public var autoScrollAction : AutoScrollAction
    public var scrollInsets : ScrollInsets
    
    public var accessibilityIdentifier: String?
    
    public var content : Content
}

This allows you to configure the list view however needed within the configure update.

Item

You can think of Item as the wrapper for the content you provide to the list โ€“ similar to how a UITableViewCell or UICollectionViewCell wraps a content view and provides other configuration options.

An Item is what you add to a section to represent a row in a list. It contains your provided content (ItemContent), alongside things like sizing, layout customization, selection behavior, reordering behavior, and callbacks which are performed when an item is selected, displayed, etc.

public struct Item<Content:ItemContent> : AnyItem
{
    public var identifier : Content.Identifier
    
    public var content : Content
    
    public var sizing : Sizing
    public var layout : ItemLayout
    
    public var selection : ItemSelection
    
    public var swipeActions : SwipeActions?
    
    public var reordering : ItemReordering?
        
    public typealias OnSelect = (Content) -> ()
    public var onSelect : OnSelect?
    
    public typealias OnDeselect = (Content) -> ()
    public var onDeselect : OnDeselect?
    
    public typealias OnDisplay = (Content) -> ()
    public var onDisplay : OnDisplay?
    
    public typealias OnEndDisplay = (Content) -> ()
    public var onEndDisplay : OnEndDisplay?
}

You can add an item to a section via either the add function, or via the += override.

section += Item(
    YourContent(title: "Hello, World!"),
    
    sizing: .default,
    selection: .notSelectable
)

However, if you want to use all default values from the Item initializer, you can skip a step and simply add your ItemContent to the section directly.

section += YourContent(title: "Hello, World!")

ItemContent

The core value type which represents an item's content.

This view model describes the content of a given row / item, via the identifier, plus the wasMoved and isEquivalent methods.

To convert an ItemContent into views for display, the createReusableContentView(:) method is called to create a reusable view to use when displaying the content (the same happens for background views as well).

To prepare the views for display, the apply(to:for:with:) method is called, which is where you push the content from your ItemContent onto the provided views.

public protocol ItemContent
{
    associatedtype IdentifierValue : Hashable

    var identifierValue : IdentifierValue { get }

    func apply(
        to views : ItemContentViews<Self>,
        for reason: ApplyReason,
        with info : ApplyItemContentInfo
    )

    func wasMoved(comparedTo other : Self) -> Bool
    func isEquivalent(to other : Self) -> Bool

    associatedtype ContentView:UIView
    static func createReusableContentView(frame : CGRect) -> ContentView

    associatedtype BackgroundView:UIView = UIView
    static func createReusableBackgroundView(frame : CGRect) -> BackgroundView

    associatedtype SelectedBackgroundView:UIView = BackgroundView
    static func createReusableSelectedBackgroundView(frame : CGRect) -> SelectedBackgroundView
}

Note however, you usually do not need to implement all these methods! For example, if your ItemContent is Equatable, you get isEquivalent for free โ€“ and by default, wasMoved is the same was isEquivalent(other:) == false.

public extension ItemContent
{
    func wasMoved(comparedTo other : Self) -> Bool
    {
        return self.isEquivalent(to: other) == false
    }
}


public extension ItemContent where Self:Equatable
{
    func isEquivalent(to other : Self) -> Bool
    {
        return self == other
    }
}

The BackgroundView and SelectedBackgroundView views also default to a plain UIView which do not display any content of their own. You only need to provide these background views if you wish to support customization of the appearance of the item during highlighting and selection.

public extension ItemContent where BackgroundView == UIView
{
    static func createReusableBackgroundView(frame : CGRect) -> BackgroundView
    {
        BackgroundView(frame: frame)
    }
}

The SelectedBackgroundView also defaults to the type of BackgroundView unless you explicitly want two different view types.

public extension ItemContent where BackgroundView == SelectedBackgroundView
{
    static func createReusableSelectedBackgroundView(frame : CGRect) -> BackgroundView
    {
        self.createReusableBackgroundView(frame: frame)
    }
}

This is all a bit abstract, so consider the following example: An ItemContent which provides a title and detail label.

struct SubtitleItem : ItemContent, Equatable
{
    var title : String
    var detail : String
    
    // ItemContent

    func apply(to views : ItemContentViews<Self>, for reason: ApplyReason, with info : ApplyItemContentInfo)
    {
        views.content.titleLabel.text = self.title
        views.content.detailLabel.text = self.detail        
    }
    
    typealias ContentView = View
    
    static func createReusableContentView(frame : CGRect) -> ContentView
    {
        View(frame: frame)
    }
    
    private final class View : UIView
    {
        let titleLabel : UILabel
        let detailLabel : UILabel
        
        ...
    }
}

HeaderFooter

How to describe a header or footer within a list. Very similar API to Item, but with less stuff, as headers and footers are display-only.

public struct HeaderFooter<Content:HeaderFooterContent> : AnyHeaderFooter
{
    public var content : Content
    
    public var sizing : Sizing
    public var layout : HeaderFooterLayout
}

You set headers and footers on sections via the header and footer parameter.

self.listView.configure { list in
    list += Section("section-1") { section in
        section.header = DemoHeader(title: "This Is A Header")
        section.footer = DemoFooter(text: "And this is a footer. Please check the EULA for details.")
    } 
}

HeaderFooterContent

Again, a similar API to ItemContent, but with a reduced surface area, given the reduced concerns of header and footers.

public protocol HeaderFooterContent
{
    func apply(to view : Appearance.ContentView, reason : ApplyReason)

    func isEquivalent(to other : Self) -> Bool
    
    associatedtype ContentView:UIView
    static func createReusableContentView(frame : CGRect) -> ContentView
    
    associatedtype BackgroundView:UIView
    static func createReusableBackgroundView(frame : CGRect) -> BackgroundView
    
    associatedtype PressedBackgroundView:UIView
    static func createReusablePressedBackgroundView(frame : CGRect) -> PressedBackgroundView
}

As is with Item, if your HeaderFooterContent is Equatable, you get isEquivalent for free.

public extension HeaderFooterContent where Self:Equatable
{    
    func isEquivalent(to other : Self) -> Bool
    {
        return self == other
    }
}

A standard implementation may look like this:

struct Header : HeaderFooterContent, Equatable
{
    var title : String

    func apply(to view : Appearance.ContentView, for reason: ApplyReason)
    {
        view.titleLabel.text = self.title       
    }
    
    typealias ContentView = View
    
    static func createReusableContentView(frame : CGRect) -> ContentView
    {
        View(frame: frame)
    }
    
    private final class View : UIView
    {
        let titleLabel : UILabel
        
        ...
    }
}

Section

Section โ€“ surprise โ€“ represents a given section in a list. Most of your interaction with Section will be through the init & builder API, as shown above.

Section("section") { section in
    section += self.podcasts.map {
        PodcastRow(podcast: $0)
    }
}

However, section has many properties to allow for configuration. You can customize the layout, the number of and layout of columns, set the header and footer, and obviously provide items, via the items property, and via the many provided overrides of the += operator.

public struct Section
{    
    public var layout : Layout
    public var columns : Columns
    
    public var header : AnyHeaderFooter?
    public var footer : AnyHeaderFooter?
    
    public var items : [AnyItem]
}

Integration With Blueprint

If you're using Blueprint integration via the BlueprintUILists module, you will also interact with the following types.

List

When using ListView directly, you'd use list.configure { list in ... } to set the content of a list.

However, Blueprint element trees are just descriptions of UI โ€“ as such, List is just a Blueprint Element which describes a list. The parameter passed to List { list in ... } is the same type (ListProperties) that is passed to list.configure { list in ... }.

var elementRepresentation : Element {
    List { list in
        list += Section("section") { section in
            
            section += self.podcasts.map {
                PodcastRow(podcast: $0)
            }
        }
    }
}

BlueprintItemContent

BlueprintItemContent simplifies the ItemContent creation process, asking you for a Blueprint Element description, instead of view types and view instances.

Unless you are supporting highlighting and selection of your ItemContent, you do not need to provide implementations of backgroundElement(:) and selectedBackgroundElement(:) โ€“ they default to returning nil. Similar to ItemContent, wasMoved(:) and isEquivalent(:) are also provided based on Equatable conformance.

public protocol BlueprintItemContent : ItemContent
{
    associatedtype IdentifierValue : Hashable

    var identifierValue : IdentifierValue { get }

    func wasMoved(comparedTo other : Self) -> Bool
    func isEquivalent(to other : Self) -> Bool

    func element(with info : ApplyItemContentInfo) -> Element
    
    func backgroundElement(with info : ApplyItemContentInfo) -> Element?

    func selectedBackgroundElement(with info : ApplyItemContentInfo) -> Element?
}

A standard BlueprintItemContent may look something like this:

struct MyPerson : BlueprintItemContent, Equatable
{
    var name : String
    var phoneNumber : String

    var identifierValue : String {
        self.name
    }
    
    func element(with info : ApplyItemContentInfo) -> Element {
        Row {
            $0.add(child: Label(text: name))
            $0.add(child: Spacer())
            $0.add(child: Label(text: name))
        }
        .inset(by: 15.0)
    }
}

BlueprintHeaderFooterContent

Similarly, BlueprintHeaderFooterContent makes creating a header or footer easy โ€“ just implement elementRepresentation, which provides the content element for your header or footer. As usual, isEquivalent(to:) is provided if your type is Equatable.

public protocol BlueprintHeaderFooterContent : HeaderFooterElement
{
    func isEquivalent(to other : Self) -> Bool

    var elementRepresentation : Element { get }
}

A standard BlueprintHeaderFooterContent may look something like this:

struct MyHeader : BlueprintHeaderFooterContent, Equatable
{
    var name : String
    var itemCount : String
    
    var elementRepresentation : Element {
        Row {
            $0.add(child: Label(text: name))
            $0.add(child: Spacer())
            $0.add(child: Label(text: itemCount))
        }
        .inset(by: 15.0)
    }
}

Getting Started

Listable is published on CocoaPods. You can add a dependency on Listable or it's Blueprint wrapper with the following in your Podspec:

s.dependency 'ListableUI'
s.dependency 'BlueprintUILists'

If you want to depend on bleeding-edge changes, you can add the pods to your Podfile via the git repo like so:

  pod 'BlueprintUILists', git: 'ssh://[email protected]:kyleve/Listable.git'
  pod 'ListableUI', git: 'ssh://[email protected]:kyleve/Listable.git'

Demo Project

If you'd like to see examples of Listable in use, clone the repo, and then run bundle exec pod install in the root of the repo. This will create the Demo/Demo.xcworkspace workspace, which you can open and run. It contains examples of various types of screens and use cases.

Other Neat Stuff

You can nest Lists in other lists.

You can nest horizontal scrolling Lists within vertical scrolling lists to create advanced, custom layouts. Listable provides a ListItemElement to make this easy.

You can override many layout parameters on a per-item and per-header/footer basis.

By setting the layout parameter on Item or HeaderFooter, you can specify the alignment of each item within a layout, how much padding it should have, how much spacing it can have, etc.

Appendix

Implementation Details

Rendering & Display

Listable is built on top of UICollectionView, with a custom UICollectionViewLayout though this is not exposed to consumers.

Performance

Internally, performance is achieved through transparent batching of content that is loaded into the collection view itself. This allows pushing large amounts of content into the list, but ListView is intelligent enough to only load, measure, diff, etc, enough of that content to display the current scroll position, plus some scroll overflow. In practice, this means that even if you put 50,000 items into a list, if the user is scrolled at the top of the table, only a few hundred items will be measured, diffed, and take up computation time during initial rendering and updates. This allows performance to remain nearly constant, regardless of what content is pushed into the list. The farther down a user scrolls, the more computation must be completed.

View State Management

Internally, every item drawn on screen and visible in the list is represented by a long-lived PresentationState instance, which tracks visible cells, sizing measurements, etc. This long lived object allows an extra layer which means it's easy to cache height calculations across multiple content updates in the list view, allowing for further performance improvements and optimizations. This is transparent to the developer.

Why?

Building rich and interactive list views and lists on iOS remains a challenge. Maintaining state and performing animations on changes is tricky and error prone. More often than not, there are lurking state bugs that result in inconsistent data or crashes that are hard to diagnose and debug.

Historically, we have managed list view state one of a few ways...

  1. Via Core Data and NSFetchedResultsController, which handles diffing and updates. However, this binds your UI tightly to the underlying core data model, which makes changes difficult and error prone. You end up needing to model UI concerns deep in your Core Data model to sort and section your data as you want. No good.

  2. Use other options such as common block-based table view or collection view builders โ€“ which abstracts some of the complexity away from developers, but it still deals in the currency of cells and views โ€“ and makes it difficult to properly handle animations and updates.

  3. Sometimes, you end up just giving up and calling reloadData() any time anything in your tableโ€™s data source changes โ€“ this sucks because users donโ€™t see animations which indicate to them what changed.

  4. Or, even worse, you end up managing insertions, deletions, and updates yourself, which usually goes something like thisโ€ฆ

Call beginUpdates

Call insertRow:atIndexPath: Call insertRow:atIndexPath: Call moveRowAtIndexPath:toIndexPath: Etc..

Call endUpdates

Assertion failure in UITableView/UICollectionView.m:20000000: The number of rows before the update is not equal to > the number of rows after the update, plus or minus the added and removed rows. You suck, nerd!

[Crash]

Needless to say, none of these options are great, and all of these are state-of-the-art circa about 2011 โ€“ which was a long time ago.

Legal Stuff

Copyright 2019 Square, Inc.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License

More Repositories

1

okhttp

Squareโ€™s meticulous HTTP client for the JVM, Android, and GraalVM.
Kotlin
45,794
star
2

retrofit

A type-safe HTTP client for Android and the JVM
HTML
43,053
star
3

leakcanary

A memory leak detection library for Android.
Kotlin
29,383
star
4

picasso

A powerful image downloading and caching library for Android
Kotlin
18,716
star
5

javapoet

A Java API for generating .java source files.
Java
10,820
star
6

moshi

A modern JSON library for Kotlin and Java.
Kotlin
9,756
star
7

okio

A modern I/O library for Android, Java, and Kotlin Multiplatform.
Kotlin
8,790
star
8

dagger

A fast dependency injector for Android and Java.
Java
7,308
star
9

crossfilter

Fast n-dimensional filtering and grouping of records.
JavaScript
6,217
star
10

PonyDebugger

Remote network and data debugging for your native iOS app using Chrome Developer Tools
Objective-C
5,864
star
11

maximum-awesome

Config files for vim and tmux.
Ruby
5,706
star
12

otto

An enhanced Guava-based event bus with emphasis on Android support.
Java
5,163
star
13

cubism

Cubism.js: A JavaScript library for time series visualization.
JavaScript
4,943
star
14

sqlbrite

A lightweight wrapper around SQLiteOpenHelper which introduces reactive stream semantics to SQL operations.
Java
4,570
star
15

android-times-square

Standalone Android widget for picking a single date from a calendar view.
Java
4,445
star
16

wire

gRPC and protocol buffers for Android, Kotlin, Swift and Java.
Kotlin
4,244
star
17

Valet

Valet lets you securely store data in the iOS, tvOS, watchOS, or macOS Keychain without knowing a thing about how the Keychain works. Itโ€™s easy. We promise.
Swift
3,989
star
18

cube

Cube: A system for time series visualization.
JavaScript
3,904
star
19

kotlinpoet

A Kotlin API for generating .kt source files.
Kotlin
3,896
star
20

java-code-styles

IntelliJ IDEA code style settings for Square's Java and Android projects.
Shell
2,957
star
21

flow

Name UI states, navigate between them, remember where you've been.
Java
2,786
star
22

spoon

Distributing instrumentation tests to all your Androids.
HTML
2,702
star
23

keywhiz

A system for distributing and managing secrets
Java
2,619
star
24

tape

A lightning fast, transactional, file-based FIFO for Android and Java.
Java
2,466
star
25

certstrap

Tools to bootstrap CAs, certificate requests, and signed certificates.
Go
2,282
star
26

mortar

A simple library that makes it easy to pair thin views with dedicated controllers, isolated from most of the vagaries of the Activity life cycle.
Java
2,157
star
27

go-jose

An implementation of JOSE standards (JWE, JWS, JWT) in Go
1,975
star
28

Cleanse

Lightweight Swift Dependency Injection Framework
Swift
1,784
star
29

assertj-android

A set of AssertJ helpers geared toward testing Android.
Java
1,577
star
30

haha

DEPRECATED Java library to automate the analysis of Android heap dumps.
Java
1,436
star
31

phrase

Phrase is an Android string resource templating library
Java
1,404
star
32

cane

Code quality threshold checking as part of your build
Ruby
1,325
star
33

anvil

A Kotlin compiler plugin to make dependency injection with Dagger 2 easier.
Kotlin
1,310
star
34

seismic

Android device shake detection.
Java
1,275
star
35

sudo_pair

Plugin for sudo that requires another human to approve and monitor privileged sudo sessions
Rust
1,240
star
36

square.github.io

A simple, static portal which outlines our open source offerings.
CSS
1,153
star
37

spacecommander

Commit fully-formatted Objective-C as a team without even trying.
Objective-C
1,126
star
38

workflow

A Swift and Kotlin library for making composable state machines, and UIs driven by those state machines.
Shell
1,124
star
39

workflow-kotlin

A Swift and Kotlin library for making composable state machines, and UIs driven by those state machines.
Kotlin
1,027
star
40

certigo

A utility to examine and validate certificates in a variety of formats
Go
941
star
41

logcat

I CAN HAZ LOGZ?
Kotlin
895
star
42

radiography

Text-ray goggles for your Android UI.
Kotlin
852
star
43

whorlwind

Makes fingerprint encryption a breeze.
Java
817
star
44

dagger-intellij-plugin

An IntelliJ IDEA plugin for Dagger which provides insight into how injections and providers are used.
Java
796
star
45

cycler

Kotlin
791
star
46

Paralayout

Paralayout is a set of simple, useful, and straightforward utilities that enable pixel-perfect layout in iOS. Your designers will love you.
Swift
786
star
47

apropos

A simple way to serve up appropriate images for every visitor.
Ruby
764
star
48

shift

shift is an application that helps you run schema migrations on MySQL databases
Ruby
735
star
49

coordinators

Simple MVWhatever for Android
Java
702
star
50

subzero

Block's Bitcoin Cold Storage solution.
C
683
star
51

Blueprint

Declarative UI construction for iOS, written in Swift
Swift
672
star
52

shuttle

String extraction, translation and export tools for the 21st century. "Moving strings around so you don't have to"
Ruby
656
star
53

gifencoder

A pure Java library implementing the GIF89a specification. Suitable for use on Android.
Java
654
star
54

pollexor

Java client for the Thumbor image service which allows you to build URIs in an expressive fashion using a fluent API.
Java
633
star
55

intro-to-d3

a D3.js tutorial
CSS
602
star
56

kochiku

Shard your builds for fun and profit
Ruby
599
star
57

curtains

Lift the curtain on Android Windows!
Kotlin
570
star
58

svelte-store

TypeScript
524
star
59

RxIdler

An IdlingResource for Espresso which wraps an RxJava Scheduler.
Java
511
star
60

burst

A unit testing library for varying test data.
Java
464
star
61

field-kit

FieldKit lets you take control of your text fields.
JavaScript
463
star
62

SuperDelegate

SuperDelegate provides a clean application delegate interface and protects you from bugs in the application lifecycle
Swift
454
star
63

otto-intellij-plugin

An IntelliJ IDEA plugin to navigate between events posted by Otto.
Java
451
star
64

js-jose

JavaScript library to encrypt/decrypt data in JSON Web Encryption (JWE) format and to sign/verify data in JSON Web Signature (JWS) format. Leverages Browser's native WebCrypto API.
JavaScript
422
star
65

sharkey

Sharkey is a service for managing certificates for use by OpenSSH
Go
395
star
66

connect-api-examples

Code samples demonstrating the functionality of the Square Connect API
JavaScript
391
star
67

fdoc

Documentation format and verification
Ruby
380
star
68

ETL

Extract, Transform, and Load data with Ruby
Ruby
377
star
69

lgtm

Simple object validation for JavaScript.
JavaScript
370
star
70

papa

PAPA: Performance of Android Production Applications
Kotlin
345
star
71

laravel-hyrule

Object-oriented, composable, fluent API for writing validations in Laravel
PHP
341
star
72

in-app-payments-flutter-plugin

Flutter Plugin for Square In-App Payments SDK
Objective-C
340
star
73

pylink

Python Library for device debugging/programming via J-Link
Python
331
star
74

workflow-swift

A Swift and Kotlin library for making composable state machines, and UIs driven by those state machines.
Swift
326
star
75

pysurvival

Open source package for Survival Analysis modeling
HTML
319
star
76

rails-auth

Modular resource-based authentication and authorization for Rails/Rack
Ruby
291
star
77

cocoapods-generate

A CocoaPods plugin that allows you to easily generate a workspace from a podspec.
Ruby
279
star
78

inspect

inspect is a collection of metrics gathering, analysis utilities for various subsystems of linux, mysql and postgres.
Go
268
star
79

Aardvark

Aardvark is a library that makes it dead simple to create actionable bug reports.
Objective-C
260
star
80

gradle-dependencies-sorter

A CLI app and Gradle plugin to sort the dependencies in your Gradle build scripts
Kotlin
253
star
81

jetpack

jet.pack: package your JRuby rack app for Jetty.
Ruby
248
star
82

luhnybin

Shell
232
star
83

auto-value-redacted

An extension for Google's AutoValue that omits redacted fields from toString().
Java
211
star
84

protoparser

Java parser for .proto schema declarations.
Java
210
star
85

squalor

Go SQL utility library
Go
205
star
86

p2

Platypus Platform: Tools for Scalable Deployment
Go
196
star
87

mimecraft

Utility for creating RFC-compliant multipart and form-encoded HTTP request bodies.
Java
195
star
88

git-fastclone

git clone --recursive on steroids
Ruby
187
star
89

zapp

Continuous Integration for KIF
Objective-C
179
star
90

metrics

Metrics Query Engine
Go
170
star
91

ruby-rrule

RRULE expansion for Ruby
Ruby
170
star
92

quotaservice

The purpose of a quota service is to prevent cascading failures in micro-service environments. The service acts as a traffic cop, slowing down traffic where necessary to prevent overloading services. For this to work, remote procedure calls (RPCs) between services consult the quota service before making a call. The service isnโ€™t strictly for RPCs between services, and can even be used to apply quotas to database calls, for example.
Go
153
star
93

wire-gradle-plugin

A Gradle plugin for generating Java code for your protocol buffer definitions with Wire.
Groovy
153
star
94

goprotowrap

A package-at-a-time wrapper for protoc, for generating Go protobuf code.
Go
148
star
95

beancounter

Utility to audit the balance of Hierarchical Deterministic (HD) wallets. Supports multisig + segwit wallets.
Go
144
star
96

rce-agent

gRPC-based Remote Command Execution Agent
Go
136
star
97

womeng_handbook

Everything you need to start or expand a women in engineering group in your community.
129
star
98

cocoapods-check

A CocoaPods plugin that shows differences between locked and installed Pods
Ruby
126
star
99

point-of-sale-android-sdk

A simple library for letting Point of Sale take in-store payments for your app using Point of Sale API.
Java
119
star
100

in-app-payments-react-native-plugin

Objective-C
119
star