IHP 1.1 is out now!

Painless Changes when the Requirements change

Thanks to Haskell's industry-leading type system you can confidently make large refactorings.

Typically you don't try to change core data structures in a rails or nodejs project after creating them. This always introduces bugs, so you avoid it, unless the advantages are really big.

With Haskell you have the confidence to change it all. The compiler will guide you through all the changes you need to do. When it finally compiles successfully again, you know it's working. This is something you need to experience once to fully understand!

Start Now

Best-in-class Type System!

Move fast, without breaking things

High Velocity, forever

Functional Software Design

Start Now

Find out what IHP has to offer

Instant Live Reloading

While Haskell is a compiled language, the built-in dev server automatically reloads your code shanges using the fastest way possible. Changes are reflected instantly. Just like good old PHP.

There's one more thing to the auto reloading in dev mode: the refresh uses a diff-based patch approach to avoid resetting the page state. This means: changes are reflected instantly. For example when you change the HSX code of a form while you already filled some fields, the filled fields keep their values. This makes building with IHP very enjoyable and addicting.

HSX

Like React's JSX. Write html code in your haskell files. This will be transformed to actual type-checked Haskell code at compile time. In HSX common errors like having a typo in an HTML attribute name or missing a closing tag will show you a compile-time error.

Automatic escaping in HSX ensures that all your views are safe against XSS attacks.

Views in IHP are pure functions. So they can never directly trigger database queries. This design enforces clear separation of concerns.

Web-based Schema Designer

To speed up your development process, IHP comes with a full set of web based dev tools. Including a database schema designer.

The visual tools are very much inspired by SmallTalk. When you start an IHP app, the first thing you see is the data structures.

Using the visual tools only edits the actual SQL statements. So if you like to stick to your text editor, you can just edit the raw SQL files. It also means you can make use of the full power of git or other VCSs.

Painless Changes when the Requirements change

Security

Common security vulnerabilities like XSS or SQL-Injection are mitigated with Haskell's powerful type system.

Productive Dev Tooling

To speed up your development process, IHP comes with a full set of web based dev tools. Including a database schema designer, a web-based code generator, a web-based repl, and much more.

SQL-Centric Design

IHP promotes the use of plain SQL over higher-level abstractions on the persistance layer. Instead of fighting complex Data Mapper ORMs, IHP provides simple database access functions that have a clear and direct mapping to the anderlying SQL statements. IHP uses your SQL definitions to provide type-safe query builders.

IHP Auto Refresh

Displaying Real-Time data in your web application without hassle. Auto Refresh offers a way to re-render veiws of your application when the underlying data changes.

learn more

The Haskell Framework for Non-Haskellers

Haskell is a great programming language.

But if Haskell is so great, why is no one using it?

Haskell is not mainstream yet because it's very hard to get into. There are lots of showstoppers where people give up on their Haskell journey. Haskell beginners typically learn how to write small functions, but it takes a lot of effort to grow beyond that and build real world applications.

A big part of the software development world is web development. While Haskell has had many great frameworks before IHP, you always needed to make a lot of decisions upfront: how to structure your project, what template library to use, what database library to use, stack or cabal, String or Text or ByteString.

But when you're just starting out with Haskell, you typically just don't know. And now you're stuck. This is where Haskell loses a lot of people.

With IHP we filled this gap. IHP is designed the other way around. It's designed to be used without any experience in Haskell. You can pick up Haskell along the way. IHP helps you to get something on the screen in a few minutes. When you see your application come together, it's easier to stick with Haskell even when it's a bit hard to learn.

Optimized for Teams

IHP comes with a completely standardized, fully-managed development environment. Setup takes just 5 minutes.

All dependencies - even the database and compiler - are managed using the nix package manager. The nix package manager makes it possible to guarantee that every team member working on a project has the same dependency versions. Byte-to-byte. This means dependency problems just cannot occur anymore. Everything is guaranteed to be the same for all developers on your team.

"Faster than SPA" Performance

Out of the box IHP comes with Turbolinks-based JS setup that delivers Faster than Single page app performance.

The time between a mouse hover event and when the user actually triggers a click is more than 100ms. We prefetch the link on hover, and when the link click is actually triggered we replace the page’s HTML. We use morphdom, a popular dom diff & patch library, for replacing the old page HTML with the new HTML. This way only the changed DOM nodes are actually touched. So this is actually very similiar to how react works. This way you can even use CSS transitions on elements.

Integrated Dev Database

Most frameworks use sqlite in development and a different database in production. This leads to problems, like sqlite not supporting foreign key constraints. If you ever had a problem caused by a missing ON DELETE behavior on a foreign key constraint, that only has happened in production, but not in development, you know the pain.

It’s best to use the same database system everywhere. But then you always need to set it up. And what happens when different projects use a different version of postgres?

In IHP we’ve found a new way to solve this problem. IHP comes bundled with a postgres server. The IHP dev server automatically starts the postgres server, creates a database and inserts your fixtures. Your app is automatically wired up with the database using a unix socket. So even when you have your own local postgres running, thanks to the unix socket, it will not collide.

IHP is the first framework that delivers this out-of-the-box experience. If you’ve used this once, you never want to go back.

IHP Server-Side Components

IHP Server-Side Components provide a toolkit for building interactive client-side functionality without needing to write too much javascript.

The design is inspired by react and redux, but is executed mainly on the server. Compared to react components, IHP components are a lot more powerful as they can access the database and can run all the business logic of your backend.

Server-Side side components can simplify certain functionality. Especially when you’re dealing with code that requires lot’s of functionality that can only be provided by the server-side.

Additionally you get type-safety and avoid the troubles of maintaining two systems.

Server-Side Components are not a replacement for react, but a tool to build certain functionality faster. In cases where low latency or offline functionality is required, server-side components are not the right solution.

instance Component BlockEditor BlockEditorController where
	initialstate = BlockEditor { postId = "..", blocks = [] }

	componentDidMount state = fetchBlocks state

	render BlockEditor { postId, blocks } = [hsx|
            <div class="blocks">
                {forEach orderedBlocks renderBlock}
            </div>
	|]

	action state AddBlock { blockType } = ..
	action state UpdateBlockParagraphText { blockId, paragraphText} = ..
	action state UpdateBlockHeadlineText { blockId, headlineText} = ..
	action state UpdateBlockImageSrc { blockId, imagesre} = ..
	action state DeleteBlock { blockId} = ..
	action state MoveBlockUp { blockId} = ..
	action state MoveBlockDown { blockId } = ..