Advanced Features

The Next Step in Textbook Evolution

Unlike traditional textbooks or even ebooks, LibreText's web-based origins allow powerful integration of advanced features. LibreTexts prides itself in embracing new technologies to enhance student engagement, as content can be so much more than just text and images. These advanced features are available to all LibreTexts. It is up to instructors to decide which ones are the best fit for their classes.

In addition to the integrations that we have already implemented, we are continuously adding new features to expand the capabilities of LibreTexts and to integrate with existing technologies at institutions such as their Learning Management Systems. Wishing for a feature that we haven't thought of yet? Don't be afraid to suggest a feature!

Embedded Multimedia

Interactive videos are a simple, yet effective way to make your content feel more dynamic. Whether you chose to embed an existing video or make your own, interactive videos are a great way to present and visualize even the most complex topics.

Dynamic Figures

Sometimes text and still images just aren't enough to model our 3D world. With dynamic figures, students can manipulate 3D objects in order to get a new perspective and understanding. Our embedded molecular viewers allow for the interactive visualization of proteins and molecules, while CalcPlot3D gives shape to a whole new dimension of mathematics.


With Jupyter, code can be embedded right into the page for students to try. Supporting many popular languages such as Python, R, and Octave, Jupyter in LibreTexts can turn a few lines of code into a dynamic illustration of concepts in action. LibreTexts is also exploring the possibility of hosting dedicated computational resources to cover the needs of more data-intensive courses. Example from bqplot under Apache License 2.0

#You can scroll this code!
import pandas as pd
import numpy as np
import os

from bqplot import (
    LogScale, LinearScale, OrdinalColorScale, ColorAxis,
    Axis, Scatter, Lines, CATEGORY10, Label, Figure, Tooltip

from ipywidgets import HBox, VBox, IntSlider, Play, jslink
initial_year = 1800
data = pd.read_json(os.path.abspath('./examples/data_files/nations.json'))
def clean_data(data):
    for column in ['income', 'lifeExpectancy', 'population']:
        data = data.drop(data[data[column].apply(len) <= 4].index)
    return data

def extrap_interp(data):
    data = np.array(data)
    x_range = np.arange(1800, 2009, 1.)
    y_range = np.interp(x_range, data[:, 0], data[:, 1])
    return y_range

def extrap_data(data):
    for column in ['income', 'lifeExpectancy', 'population']:
        data[column] = data[column].apply(extrap_interp)
    return data
data = clean_data(data)
data = extrap_data(data)
income_min, income_max = np.min(data['income'].apply(np.min)), np.max(data['income'].apply(np.max))
life_exp_min, life_exp_max = np.min(data['lifeExpectancy'].apply(np.min)), np.max(data['lifeExpectancy'].apply(np.max))
pop_min, pop_max = np.min(data['population'].apply(np.min)), np.max(data['population'].apply(np.max))
def get_data(year):
    year_index = year - 1800
    income = data['income'].apply(lambda x: x[year_index])
    life_exp = data['lifeExpectancy'].apply(lambda x: x[year_index])
    pop =  data['population'].apply(lambda x: x[year_index])
    return income, life_exp, pop
tt = Tooltip(fields=['name', 'x', 'y'], labels=['Country Name', 'Income per Capita', 'Life Expectancy'])
year_label = Label(x=[0.75], y=[0.10], default_size=46, font_weight='bolder', colors=['orange'],
                   text=[str(initial_year)], enable_move=True)
x_sc = LogScale(min=income_min, max=income_max)
y_sc = LinearScale(min=life_exp_min, max=life_exp_max)
c_sc = OrdinalColorScale(domain=data['region'].unique().tolist(), colors=CATEGORY10[:6])
size_sc = LinearScale(min=pop_min, max=pop_max)
ax_y = Axis(label='Life Expectancy', scale=y_sc, orientation='vertical', side='left', grid_lines='solid')
ax_x = Axis(label='Income per Capita', scale=x_sc, grid_lines='solid')
# Start with the first year's data
cap_income, life_exp, pop = get_data(initial_year)
wealth_scat = Scatter(x=cap_income, y=life_exp, color=data['region'], size=pop,
                      names=data['name'], display_names=False,
                      scales={'x': x_sc, 'y': y_sc, 'color': c_sc, 'size': size_sc},
                      default_size=4112, tooltip=tt, animate=True, stroke='Black',
                      unhovered_style={'opacity': 0.5})
nation_line = Lines(x=data['income'][0], y=data['lifeExpectancy'][0], colors=['Gray'],
                       scales={'x': x_sc, 'y': y_sc}, visible=False)
time_interval = 10
fig = Figure(marks=[wealth_scat, year_label, nation_line], axes=[ax_x, ax_y],
             title='Health and Wealth of Nations', animation_duration=time_interval)
year_slider = IntSlider(min=1800, max=2008, step=1, description='Year', value=initial_year)
def hover_changed(change):
    if is not None:
        nation_line.x = data[data['name'] == wealth_scat.names[]]['income'].values[0]
        nation_line.y = data[data['name'] == wealth_scat.names[]]['lifeExpectancy'].values[0]
        nation_line.visible = True
        nation_line.visible = False
wealth_scat.observe(hover_changed, 'hovered_point')
def year_changed(change):
    wealth_scat.x, wealth_scat.y, wealth_scat.size = get_data(year_slider.value)
    year_label.text = [str(year_slider.value)]

year_slider.observe(year_changed, 'value')
play_button = Play(min=1800, max=2008, interval=time_interval)
jslink((play_button, 'value'), (year_slider, 'value'))
VBox([HBox([play_button, year_slider]), fig])


Hypothesis is a annotation overlay that allows for both public and class-based collaboration. Some courses use this as a contextual discussion forum to ask clarifying questions or to highlight the most important content.

Print on Demand

If you like having something tangible to study off of, every page has an option to download and print a PDF version. This is a great alternative for the classroom if you want to limit the usage of electronic devices in class or if you have exercises for students to work out on paper.

Complete Printed Version - New!

Want an entire LibreText as a physical copy? LibreTexts is planning on expanding its print system such that you can request a full LibreText to print yourself or with a non-profit partner. This static version lacks the advanced features and always up-to-date nature of the actual website. Still, this version of a LibreText provides ultimate portability for those that want to retain the feel of a traditional textbook. A typical 500 page book can be printed and bound in softcover for only $12; a hardbound copy printed in color can be obtained for $35. All cost is dedicated to printing the resource; LibreTexts does not generate a profit from print copies. Check out our Printing with Lulu xPress Guide to get started!

One Minute Import into LMS

Using the LTI Common Cartridge system, it is possible to import a LibreText into your new course as a set of links. The common cartridge system is compatible with common LMS software such as Canvas, D2L, Moodle, and Blackboard. This is a speedy methods for setting up assigned or recommended readings without having to manually copy over the links. Check out our LMS Common Cartridge Guide to get started! For a more dynamic integration into the LMS, see our plan for Deep LMS Integration below

Imported Open Textbooks - In Beta

Adapting an existing LibreText allows for the freedom to shape the course content without having to start from scratch. With Imported eTextbooks, LibreTexts can integrate external Open Textbook content from other sites such as from Pressbooks and allow for customization and stronger integrations. To respect and comply with licensing and copyright protections, only content with a CC BY-NC-SA, equivalent, or less restrictive license will be imported.

OER Remixer

A tenet of Open Education Resources is the freedom to adapt and customize content. With the OER Remixer, instructors and other authors can rapidly assemble and remix their own LibreText from the entire breadth of LibreTexts content available, including our content from other subjects. The OER Remixer is available for everyone to try out in demonstration mode here, and all you need to finish publishing your LibreText is to contact us to set up an Instructor account.

OER Remixer

OEI Compliance - Coming Soon

The Online Education Initiative (OEI) is a collaborative effort among California Community Colleges (CCCs) to ensure that significantly more students are able to complete their educational goals by increasing both access to and success in high-quality online courses. After our review process is complete, Instructors will be able to select LibreTexts that conform to OEI accessibility standards and rubric directly from Canvas Commons. OEI is quickly expanding to include many of the California Community Colleges, and it takes place in Canvas, which means that an estimated hundreds of thousands of students will be taking Canvas courses through OEI in the next few years.

Deep LMS Integration - Coming Soon

LibreTexts is planning on using Tsugi to allow increased interoperability with common LMS software such as Canvas, D2L, Moodle, and Blackboard. LibreTexts will be able to update course modules synchronously in the LMS as they are changed by the instructor and reporting grades from assessment modules. Our vision is for LibreTexts to utilize this integration with your LMS to evolve from just a content platform into a complete hub for student learning and assessment.

WeBWork - In Development

WeBWork is a popular homework problems platform for assessing student performance. WeBWork and other assessment platforms can be directly embedded within the course content to keep students accountable for understanding the content. The integration of LibreTexts with Learning Management Systems will then allow for the results to be integrated automatically back into your LMS, providing an all-in-one solution.