# Grist Grist is a modern relational spreadsheet. It combines the flexibility of a spreadsheet with the robustness of a database. * `grist-core` (this repo) has what you need to run a powerful spreadsheet hosting server. * [`grist-electron`](https://github.com/gristlabs/grist-electron) is a Linux/macOS/Windows desktop app for viewing and editing spreadsheets stored locally. * [`grist-static`](https://github.com/gristlabs/grist-static) is a fully in-browser build of Grist for displaying spreadsheets on a website without back-end support. The `grist-core` repo is the heart of Grist, including the hosted services offered by [Grist Labs](https://getgrist.com), an NYC-based company 🇺🇸 and Grist's main developer. The French government agency [ANCT Données et Territoires](https://donnees.incubateur.anct.gouv.fr/toolbox/grist) 🇫🇷 has also made significant contributions to the codebase. The `grist-core`, `grist-electron`, and `grist-static` repositories are all open source (Apache License, Version 2.0). > Questions? Feedback? Want to share what you're building with Grist? Join our [official Discord server](https://discord.gg/MYKpYQ3fbP) or visit our [Community forum](https://community.getgrist.com/). https://user-images.githubusercontent.com/118367/151245587-892e50a6-41f5-4b74-9786-fe3566f6b1fb.mp4 ## 2024 - We're hiring a Systems Engineer! We are looking for a friendly, capable engineer to join our small team. You will have broad responsibility for the ease of installation and maintenance of Grist as an application and service, by our clients, by self-hosters, and by ourselves. Read the [full job posting](https://www.getgrist.com/job-systems-engineer/) or jump into the puzzle that comes with it by just running this: ``` docker run -it gristlabs/grist-twist ``` ## Features Grist is a hybrid database/spreadsheet, meaning that: - Columns work like they do in databases: they are named, and they hold one kind of data. - Columns can be filled by formula, spreadsheet-style, with automatic updates when referenced cells change. This difference can confuse people coming directly from Excel or Google Sheets. Give it a chance! There's also a [Grist for Spreadsheet Users](https://www.getgrist.com/blog/grist-for-spreadsheet-users/) article to help get you oriented. If you're coming from Airtable, you'll find the model familiar (and there's also our [Grist vs Airtable](https://www.getgrist.com/blog/grist-v-airtable/) article for a direct comparison). Here are some specific feature highlights of Grist: * Python formulas. - Full [Python syntax is supported](https://support.getgrist.com/formulas/#python), including the standard library. - Many [Excel functions](https://support.getgrist.com/functions/) also available. - An [AI Assistant](https://www.getgrist.com/ai-formula-assistant/) specifically tuned for formula generation (using OpenAI gpt-3.5-turbo or [Llama](https://ai.meta.com/llama/) via llama-cpp-python). * A portable, self-contained format. - Based on SQLite, the most widely deployed database engine. - Any tool that can read SQLite can read numeric and text data from a Grist file. - Enables [backups](https://support.getgrist.com/exports/#backing-up-an-entire-document) that you can confidently restore in full. - Great for moving between different hosts. * Can be displayed on a static website with [`grist-static`](https://github.com/gristlabs/grist-static) – no special server needed. * A self-contained desktop app for viewing and editing locally: [`grist-electron`](https://github.com/gristlabs/grist-electron). * Convenient editing and formatting features. - Choices and [choice lists](https://support.getgrist.com/col-types/#choice-list-columns), for adding colorful tags to records. - [References](https://support.getgrist.com/col-refs/#creating-a-new-reference-list-column) and reference lists, for cross-referencing records in other tables. - [Attachments](https://support.getgrist.com/col-types/#attachment-columns), to include media or document files in records. - Dates and times, toggles, and special numerics such as currency all have specialized editors and formatting options. - [Conditional Formatting](https://support.getgrist.com/conditional-formatting/), letting you control the style of cells with formulas to draw attention to important information. * Drag-and-drop dashboards. - [Charts](https://support.getgrist.com/widget-chart/), [card views](https://support.getgrist.com/widget-card/) and a [calendar widget](https://support.getgrist.com/widget-calendar/) for visualization. - [Summary tables](https://support.getgrist.com/summary-tables/) for summing and counting across groups. - [Widget linking](https://support.getgrist.com/linking-widgets/) streamlines filtering and editing data. Grist has a unique approach to visualization, where you can lay out and link distinct widgets to show together, without cramming mixed material into a table. - [Filter bar](https://support.getgrist.com/search-sort-filter/#filter-buttons) for quick slicing and dicing. * [Incremental imports](https://support.getgrist.com/imports/#updating-existing-records). - Import a CSV of the last three months activity from your bank... - ...and import new activity a month later without fuss or duplication. * Integrations. - A [REST API](https://support.getgrist.com/api/), [Zapier actions/triggers](https://support.getgrist.com/integrators/#integrations-via-zapier), and support from similar [integrators](https://support.getgrist.com/integrators/). - Import/export to Google drive, Excel format, CSV. - Link data with [custom widgets](https://support.getgrist.com/widget-custom/#_top), hosted externally. - Configurable outgoing webhooks. * [Many templates](https://templates.getgrist.com/) to get you started, from investment research to organizing treasure hunts. * Access control options. - (You'll need SSO logins set up to make use of these options; [`grist-omnibus`](https://github.com/gristlabs/grist-omnibus) has a prepackaged solution if configuring this feels daunting) - Share [individual documents](https://support.getgrist.com/sharing/), workspaces, or [team sites](https://support.getgrist.com/team-sharing/). - Control access to [individual rows, columns, and tables](https://support.getgrist.com/access-rules/). - Control access based on cell values and user attributes. * Self-maintainable. - Useful for intranet operation and specific compliance requirements. * Sandboxing options for untrusted documents. - On Linux or with Docker, you can enable [gVisor](https://github.com/google/gvisor) sandboxing at the individual document level. - On macOS, you can use native sandboxing. - On any OS, including Windows, you can use a wasm-based sandbox. * Translated to many languages. * `F1` key brings up some quick help. This used to go without saying, but in general Grist has good keyboard support. * We post progress on [𝕏 or Twitter or whatever](https://twitter.com/getgrist) and publish [monthly newsletters](https://support.getgrist.com/newsletters/). If you are curious about where Grist is heading, see [our roadmap](https://github.com/gristlabs/grist-core/projects/1), drop a question in [our forum](https://community.getgrist.com), or browse [our extensive documentation](https://support.getgrist.com). ## Using Grist If you just want a quick demo of Grist: * You can try Grist out at the hosted service run by Grist Labs at [docs.getgrist.com](https://docs.getgrist.com) (no registration needed). * Or you can see a fully in-browser build of Grist at [gristlabs.github.io/grist-static](https://gristlabs.github.io/grist-static/). * Or you can download Grist as a desktop app from [github.com/gristlabs/grist-electron](https://github.com/gristlabs/grist-electron). To get `grist-core` running on your computer with [Docker](https://www.docker.com/get-started), do: ```sh docker pull gristlabs/grist docker run -p 8484:8484 -it gristlabs/grist ``` Then visit `http://localhost:8484` in your browser. You'll be able to create, edit, import, and export documents. To preserve your work across docker runs, share a directory as `/persist`: ```sh docker run -p 8484:8484 -v $PWD/persist:/persist -it gristlabs/grist ``` Get templates at [templates.getgrist.com](https://templates.getgrist.com) for payroll, inventory management, invoicing, D&D encounter tracking, and a lot more, or use any document you've created on [docs.getgrist.com](https://docs.getgrist.com). If you need to change the port Grist runs on, set a `PORT` variable, don't just change the port mapping: ``` docker run --env PORT=9999 -p 9999:9999 -v $PWD/persist:/persist -it gristlabs/grist ``` To enable gVisor sandboxing, set `--env GRIST_SANDBOX_FLAVOR=gvisor`. This should work with default docker settings, but may not work in all environments. You can find a lot more about configuring Grist, setting up authentication, and running it on a public server in our [Self-Managed Grist](https://support.getgrist.com/self-managed/) handbook. ## Building from source To build Grist from source, follow these steps: yarn install yarn run build:prod yarn run install:python yarn start # Grist will be available at http://localhost:8484/ Grist formulas in documents will be run using Python executed directly on your machine. You can configure sandboxing using a `GRIST_SANDBOX_FLAVOR` environment variable. * On macOS, `export GRIST_SANDBOX_FLAVOR=macSandboxExec` uses the native `sandbox-exec` command for sandboxing. * On Linux with [gVisor's runsc](https://github.com/google/gvisor) installed, `export GRIST_SANDBOX_FLAVOR=gvisor` is an option. * On any OS including Windows, `export GRIST_SANDBOX_FLAVOR=pyodide` is available. These sandboxing methods have been written for our own use at Grist Labs and may need tweaking to work in your own environment - pull requests very welcome here! ## Logins Like git, Grist has features to track document revision history. So for full operation, Grist expects to know who the user modifying a document is. Until it does, it operates in a limited anonymous mode. To get you going, the docker image is configured so that when you click on the "sign in" button Grist will attribute your work to `you@example.com`. Change this by setting `GRIST_DEFAULT_EMAIL`: ``` docker run --env GRIST_DEFAULT_EMAIL=my@email -p 8484:8484 -v $PWD/persist:/persist -it gristlabs/grist ``` You can change your name in `Profile Settings` in the [User Menu](https://support.getgrist.com/glossary/#user-menu). For multi-user operation, or if you wish to access Grist across the public internet, you'll want to connect it to your own Single Sign-On service. There are a lot of ways to do this, including [SAML and forward authentication](https://support.getgrist.com/self-managed/#how-do-i-set-up-authentication). Grist has been tested with [Authentik](https://goauthentik.io/), [Auth0](https://auth0.com/), and Google/Microsoft sign-ins via [Dex](https://dexidp.io/). ## Translations We use [Weblate](https://hosted.weblate.org/engage/grist/) to manage translations. Thanks to everyone who is pitching in. Thanks especially to the ANCT developers who did the hard work of making a good chunk of the application localizable. Merci bien! ## Why free and open source software This repository, `grist-core`, is maintained by Grist Labs. Our flagship product available at [getgrist.com](https://www.getgrist.com) is built from the code you see here, combined with business-specific software designed to scale to many users, handle billing, etc. Grist Labs is an open-core company. We offer Grist hosting as a service, with free and paid plans. We also develop and sell features related to Grist using a proprietary license, targeted at the needs of enterprises with large self-managed installations. We see data portability and autonomy as a key value, and `grist-core` is an essential part of that. We are committed to maintaining and improving the `grist-core` codebase, and to be thoughtful about how proprietary offerings impact data portability and autonomy. By opening its source code and offering an [OSI](https://opensource.org/)-approved free license, Grist benefits its users: - **Developer community.** The freedom to examine source code, make bug fixes, and develop new features is a big deal for a general-purpose spreadsheet-like product, where there is a very long tail of features vital to someone somewhere. - **Increased trust.** Because anyone can examine the source code, “security by obscurity” is not an option. Vulnerabilities in the code can be found by others and reported before they cause damage. - **Independence.** Grist is available to you regardless of the fortunes of the Grist Labs business, since it is open source and can be self-hosted. Using our hosted solution is convenient, but you are not locked in. - **Price flexibility.** If you are low on funds but have time to invest, self-hosting is a great option to have. And DIY users may have the technical savvy and motivation to delve in and make improvements, which can benefit all users of Grist. - **Extensibility.** For developers, having the source open makes it easier to build extensions (such as [Custom Widgets](https://support.getgrist.com/widget-custom/)). You can more easily include Grist in your pipeline. And if a feature is missing, you can just take the source code and build on top of it. For more on Grist Labs' history and principles, see our [About Us](https://www.getgrist.com/about/) page. ## Sponsors
## Reviews * [Grist on ProductHunt](https://www.producthunt.com/posts/grist-2) * [Grist on AppSumo](https://appsumo.com/products/grist/) (life-time deal is sold out) * [Capterra](https://www.capterra.com/p/232821/Grist/#reviews), [G2](https://www.g2.com/products/grist/reviews), [TrustRadius](https://www.trustradius.com/products/grist/reviews) ## Environment variables Grist can be configured in many ways. Here are the main environment variables it is sensitive to: Variable | Purpose -------- | ------- ALLOWED_WEBHOOK_DOMAINS | comma-separated list of permitted domains to use in webhooks (e.g. webhook.site,zapier.com). You can set this to `*` to allow all domains, but if doing so, we recommend using a carefully locked-down proxy (see `GRIST_HTTPS_PROXY`) if you do not entirely trust users. Otherwise services on your internal network may become vulnerable to manipulation. APP_DOC_URL | doc worker url, set when starting an individual doc worker (other servers will find doc worker urls via redis) APP_DOC_INTERNAL_URL | like `APP_DOC_URL` but used by the home server to reach the server using an internal domain name resolution (like in a docker environment). Defaults to `APP_DOC_URL` APP_HOME_URL | url prefix for home api (home and doc servers need this) APP_STATIC_URL | url prefix for static resources APP_STATIC_INCLUDE_CUSTOM_CSS | set to "true" to include custom.css (from APP_STATIC_URL) in static pages APP_UNTRUSTED_URL | URL at which to serve/expect plugin content. GRIST_ADAPT_DOMAIN | set to "true" to support multiple base domains (careful, host header should be trustworthy) GRIST_ALLOWED_HOSTS | comma-separated list of permitted domains origin for requests (e.g. my.site,another.com) GRIST_APP_ROOT | directory containing Grist sandbox and assets (specifically the sandbox and static subdirectories). GRIST_BACKUP_DELAY_SECS | wait this long after a doc change before making a backup GRIST_DATA_DIR | directory in which to store document caches. GRIST_DEFAULT_EMAIL | if set, login as this user if no other credentials presented GRIST_DEFAULT_PRODUCT | if set, this controls enabled features and limits of new sites. See names of PRODUCTS in Product.ts. GRIST_DEFAULT_LOCALE | Locale to use as fallback when Grist cannot honour the browser locale. GRIST_DOMAIN | in hosted Grist, Grist is served from subdomains of this domain. Defaults to "getgrist.com". GRIST_EXPERIMENTAL_PLUGINS | enables experimental plugins GRIST_ENABLE_REQUEST_FUNCTION | enables the REQUEST function. This function performs HTTP requests in a similar way to `requests.request`. This function presents a significant security risk, since it can let users call internal endpoints when Grist is available publicly. This function can also cause performance issues. Unset by default. GRIST_HIDE_UI_ELEMENTS | comma-separated list of UI features to disable. Allowed names of parts: `helpCenter,billing,templates,createSite,multiSite,multiAccounts,sendToDrive,tutorials`. If a part also exists in GRIST_UI_FEATURES, it will still be disabled. GRIST_HOME_INCLUDE_STATIC | if set, home server also serves static resources GRIST_HOST | hostname to use when listening on a port. GRIST_HTTPS_PROXY | if set, use this proxy for webhook payload delivery. GRIST_ID_PREFIX | for subdomains of form o-*, expect or produce o-${GRIST_ID_PREFIX}*. GRIST_IGNORE_SESSION | if set, Grist will not use a session for authentication. GRIST_INST_DIR | path to Grist instance configuration files, for Grist server. GRIST_LIST_PUBLIC_SITES | if set to true, sites shared with the public will be listed for anonymous users. Defaults to false. GRIST_MANAGED_WORKERS | if set, Grist can assume that if a url targeted at a doc worker returns a 404, that worker is gone GRIST_MAX_UPLOAD_ATTACHMENT_MB | max allowed size for attachments (0 or empty for unlimited). GRIST_MAX_UPLOAD_IMPORT_MB | max allowed size for imports (except .grist files) (0 or empty for unlimited). GRIST_OFFER_ALL_LANGUAGES | if set, all translated langauages are offered to the user (by default, only languages with a special 'good enough' key set are offered to user). GRIST_ORG_IN_PATH | if true, encode org in path rather than domain GRIST_PAGE_TITLE_SUFFIX | a string to append to the end of the `