diff --git a/docs/Doxyfile.in-mcss b/docs/Doxyfile.in-mcss
index 8f44493429..6a7abc7a25 100644
--- a/docs/Doxyfile.in-mcss
+++ b/docs/Doxyfile.in-mcss
@@ -3,4 +3,17 @@ GENERATE_HTML = YES
GENERATE_XML = YES
XML_PROGRAMLISTING = NO
M_SHOW_UNDOCUMENTED = YES
-EXTRACT_ALL = YES
\ No newline at end of file
+EXTRACT_ALL = YES
+
+ALIASES += \
+ "vt=vt" \
+ "m_div{1}=@xmlonly@endxmlonly" \
+ "m_enddiv=@xmlonly@endxmlonly" \
+ "m_span{1}=@xmlonly@endxmlonly" \
+ "m_endspan=@xmlonly@endxmlonly" \
+ "m_class{1}=@xmlonly@endxmlonly" \
+ "m_footernavigation=@xmlonly@endxmlonly" \
+ "m_examplenavigation{2}=@xmlonly@endxmlonly" \
+ "m_keywords{1}=@xmlonly@endxmlonly" \
+ "m_keyword{3}=@xmlonly@endxmlonly" \
+ "m_enum_values_as_keywords=@xmlonly@endxmlonly"
diff --git a/scripts/build_vt.pl b/scripts/build_vt.pl
index 89c51093a4..49b56f46dc 100755
--- a/scripts/build_vt.pl
+++ b/scripts/build_vt.pl
@@ -154,6 +154,7 @@ sub mk {
-DCMAKE_BUILD_TYPE=$build_mode \\
-DCMAKE_VERBOSE_MAKEFILE:BOOL=$verbose \\
-DCMAKE_CXX_COMPILER=$cxx \\
+ -Dvt_doxygen_enabled:BOOL=true\\
-DCMAKE_C_COMPILER=$cc \\
${mpi_str}
CMAKESTR
diff --git a/src/active-messenger.md b/src/active-messenger.md
new file mode 100644
index 0000000000..8a044c9322
--- /dev/null
+++ b/src/active-messenger.md
@@ -0,0 +1,23 @@
+
+\page active-messenger Active Messenger
+\brief Asynchronous send/receive of messages
+
+The active messenger, accessed via `vt::theMsg()`, asynchronously sends and
+receives messages across nodes using MPI internally. When sending a message, it
+uses the \vt registry to consistently dispatch messages and data to handlers
+(function pointers, functors, or methods) across nodes (even with address space
+randomization). Each message contains an envelope `vt::Envelope` to store
+meta-data associated with the message, such as the destination and handler to
+trigger when it arrives. Sending a message entails setting up the envelope,
+optionally serializing the message (depending on whether the serialize overload is
+present), and then using `MPI_Isend` to asynchronously transfer the bytes to the
+destination node. On the receive side, the active messenger is always probing for a
+incoming message and begins a transfer when it discovers one. The \vt scheduler
+polls the active messenger to make progress on any incoming messages.
+
+\copydoc vt::messaging::ActiveMessenger
+
+\section am-simple-example Sending a message
+
+\code{.cpp}
+\endcode
\ No newline at end of file
diff --git a/src/context.md b/src/context.md
new file mode 100644
index 0000000000..3115b845bb
--- /dev/null
+++ b/src/context.md
@@ -0,0 +1,36 @@
+
+\page context Context
+\brief Node-aware context
+
+The context component, accessed via `vt::theContext()`, provides context-aware
+querying of the current node (analogous to MPI's \c MPI_Comm_rank), number of
+nodes (analogous to MPI's \c MPI_Comm_size), and kernel threading/ULT
+information if worker threads are enabled. The context also provides the MPI
+communicator that an instance of \vt is currently using.
+
+\copybrief vt::ctx::Context
+\copydetails vt::ctx::Context
+
+\subsection get-node Current node/rank
+
+\copybrief vt::ctx::Context::getNode()
+
+To get the current node, one may query this method:
+
+\code{.cpp}
+vt::NodeType this_node = vt::theContext()->getNode();
+\endcode
+
+\subsection get-num-nodes Number of nodes/ranks
+
+\copybrief vt::ctx::Context::getNumNodes()
+
+To get the number of nodes or ranks that an instance of \vt is using, one may
+query this method:
+
+\code{.cpp}
+vt::NodeType num_nodes = vt::theContext()->getNumNodes();
+\endcode
+
+\note The result from \c getNode or \c getNumNodes will depend on the
+communicator that was passed to VT during initialization.
\ No newline at end of file
diff --git a/src/vt.md b/src/vt.md
new file mode 100644
index 0000000000..3baa3b3dff
--- /dev/null
+++ b/src/vt.md
@@ -0,0 +1,95 @@
+
+\page introduction Introduction to DARMA/vt
+\brief Overview of functionality in \vt
+
+\tableofcontents
+
+\section what-is What is vt?
+
+\vt is an active messaging layer that utilizes C++ object virtualization to
+manage virtual endpoints with automatic location management. \vt is directly
+built on top of MPI to provide efficient portability across different machine
+architectures. Empowered with virtualization, \vt can automatically perform
+dynamic load balancing to schedule scientific applications across diverse
+platforms with minimal user input.
+
+\vt abstracts the concept of a `node`/`rank`/`worker`/`thread` so a program can
+be written in terms of virtual entities that are location independent. Thus,
+they can be automatically migrated and thereby executed on varying hardware
+resources without explicit programmer mapping, location, and communication
+management.
+
+\section vt-features Features in vt
+
+- Active messaging to type-safe handlers across nodes
+- Groups for scalable construction of node subsets
+- Optional serialization of messages
+- Termination detection across entire or subset of DAG with \e epochs
+- Opaque callbacks/pipes to generalized endpoints
+- Efficient memory pooling for message allocation
+- RDMA using MPI one-sided for data transfer
+- Asynchronous Collectives across nodes/groups (scatter, async barrier, reduce, ...)
+- General scheduler with prioritization
+- Built-in interoperability with MPI and threading libraries (Kokkos, OpenMP, ...)
+- Object groups for node-level encapsulation
+- Virtual contexts for migratable virtualization and dispatch
+- Abstractions for multi-dimensional indices, mapping, and linearization
+- Virtual collections (dense, sparse, dynamic insertable) for decomposing domains
+- Fully distributed load balancer for virtual entities
+
+\section vt-components Components in vt
+
+| Component | Singleton | Details |
+| --------------------------- | ------------------- | --------------------------- |
+| \subpage context | `vt::theContext()` | \copybrief context |
+| \subpage active-messenger | `vt::theMsg()` | \copybrief active-messenger |
+
+\section vt-hello-world Example
+
+\m_class{m-block m-success}
+\parblock
+ \m_class{m-code-figure} \parblock
+ \code{.cpp}
+ struct HelloMsg : vt::Message {
+ HelloMsg(vt::NodeType in_from) : from(in_from) { }
+ vt::NodeType from = 0;
+ };
+
+ void hello_world(HelloMsg* msg) {
+ vt::NodeType this_node = vt::theContext()->getNode();
+ fmt::print("{}: Hello from node {}\n", this_node, msg->from);
+ }
+
+ int main(int argc, char** argv) {
+ vt::initialize(argc, arv);
+
+ vt::NodeType this_node = vt::theContext()->getNode();
+ vt::NodeType num_nodes = vt::theContext()->getNumNodes();
+
+ if (this_node == 0) {
+ auto msg = vt::makeMessage(this_node);
+ vt::theMsg()->broadcastMsg(msg.get());
+ }
+
+ vt::finalize();
+ return 0;
+ }
+ \endcode
+
+ Running:
+
+ \code{.shell-session}
+ $ mpirun -n 4 ./hello_world
+ \endcode
+
+ Output:
+ \code{.shell-session}
+ 3: Hello from node 0
+ 1: Hello from node 0
+ 2: Hello from node 0
+ \endcode
+
+ \note An active message broadcast sends to all nodes except for
+the sender (root of the broadcast).
+ \endparblock
+\endparblock
\ No newline at end of file